DDD888 发表于 30-6-2016 19:34:23

C++ atom question

I don't understand why z.load() show value 2.

Can you explain the idea to me?

Thanks in advance :loveliness:

makefile
default: hello

hello: main.cpp makefile
      g++ -std=c++11 -Wpedantic -Wall -O3 -g -lrt main.cpp -o hello -pthread -Wl,--no-as-needed

main.cpp source code
<atomic>
#include <thread>
#include <iostream>
#include <assert.h>

std::atomic<bool> x,y;
std::atomic<int> z;

void
write_x()
{
      x.store(true, std::memory_order_release);
}

void
write_y()
{
      y.store(true, std::memory_order_release);
}

void
read_x_then_y()
{
      while (!x.load(std::memory_order_acquire));
   
      if (y.load(std::memory_order_acquire)) {
                ++z;
      }
}

void
read_y_then_x()
{
      while (!y.load(std::memory_order_acquire));
   
      if (x.load(std::memory_order_acquire)) {
                ++z;
      }
}

int
main()
{
      x = false;
      y = false;
      z = 0;
   
      std::thread a(write_x);
      std::thread b(write_y);
      std::thread c(read_x_then_y);
      std::thread d(read_y_then_x);
   
      a.join();
      b.join();
      c.join();
      d.join();
   
      std::cout << z.load() << std::endl;
      assert(z.load() != 0);
      //assert(z.load()==0);
}

clarkli 发表于 30-6-2016 22:58:16

因为x和y都是true,所以++z执行了两次?

DDD888 发表于 1-7-2016 06:28:58

clarkli 发表于 30-6-2016 22:58
因为x和y都是true,所以++z执行了两次?

They are running in multiple threads, the order is not controlled. If they are running in single thread or main thread, it is easy to understand the logic.

clarkli 发表于 1-7-2016 21:17:14

DDD888 发表于 1-7-2016 06:28
They are running in multiple threads, the order is not controlled. If they are running in single t ...

所以看缘分,我在VM里面跑的结果大部分是1,偶尔是2

DDD888 发表于 2-7-2016 06:13:21

clarkli 发表于 1-7-2016 21:17
所以看缘分,我在VM里面跑的结果大部分是1,偶尔是2

That is strange. I always got 2

clarkli 发表于 2-7-2016 12:41:35

和操作系统线程调度有关。
换台电脑,或者换个系统结果可能就不一样了。这个代码是不能在生产中用的

DDD888 发表于 2-7-2016 16:12:57

本帖最后由 DDD888 于 2-7-2016 16:26 编辑

clarkli 发表于 2-7-2016 12:41
和操作系统线程调度有关。
换台电脑,或者换个系统结果可能就不一样了。这个代码是不能在生产中用的

The trouble for me is that I do not understand that source code.

I understand following code :loveliness:
#include <atomic>
#include <thread>
#include <iostream>
#include <assert.h>

std::atomic<int> data;
std::atomic<bool> sync1(false), sync2(false);

void
thread_1()
{
      data.store(42, std::memory_order_relaxed);
      data.store(97, std::memory_order_relaxed);
      data.store(17, std::memory_order_relaxed);
      data.store(-141, std::memory_order_relaxed);
      data.store(2003, std::memory_order_relaxed);
   
      sync1.store(true, std::memory_order_release);
}

void
thread_2()
{
      while(!sync1.load(std::memory_order_acquire));

      sync2.store(true,std::memory_order_release);
}

void
thread_3()
{
      while(!sync2.load(std::memory_order_acquire));

      assert(data.load(std::memory_order_relaxed) == 42);
      assert(data.load(std::memory_order_relaxed) == 97);
      assert(data.load(std::memory_order_relaxed) == 17);
      assert(data.load(std::memory_order_relaxed) == -141);
      assert(data.load(std::memory_order_relaxed) == 2003);
}

int
main()
{
      std::thread a(thread_1);
      std::thread b(thread_2);
      std::thread c(thread_3);

      a.join();
      b.join();
      c.join();
}

clarkli 发表于 3-7-2016 18:45:23

DDD888 发表于 2-7-2016 16:12
The trouble for me is that I do not understand that source code.

I understand following code...

不理解为什么输出2还是不理解为什么那样写?:lol

DDD888 发表于 3-7-2016 18:54:29

clarkli 发表于 3-7-2016 18:45
不理解为什么输出2还是不理解为什么那样写?

不理解为什么输出2

clarkli 发表于 3-7-2016 23:13:00

DDD888 发表于 3-7-2016 18:54
不理解为什么输出2

执行顺序可能是:
write_x(); // x is now true
write_y(); // y is now true
read_x_then_y(); // x and y are both true; execute '++z'
read_y_then_x(); // x and y are both true; execute '++z'

DDD888 发表于 4-7-2016 09:08:51

clarkli 发表于 3-7-2016 23:13
执行顺序可能是:
write_x(); // x is now true
write_y(); // y is now true


Thanks

But that is a possibility which I am sure can happen. My question is what must happen. Can it be 0?

clarkli 发表于 4-7-2016 21:11:19

不会,++z至少会被执行一次

DDD888 发表于 5-7-2016 08:20:05

clarkli 发表于 4-7-2016 21:11
不会,++z至少会被执行一次

Why?

clarkli 发表于 5-7-2016 20:08:45

以read_x_then_y()为例

while (!x.load(std::memory_order_acquire));
   
if (y.load(std::memory_order_acquire)) {
    ++z;
}

++z不被执行的唯一可能情况是x == true && y == false,而一旦x为true,read_y_then_x()中的++z就必然会被执行。因此++z至少被执行一次。

DDD888 发表于 6-7-2016 06:10:22

clarkli 发表于 5-7-2016 20:08
以read_x_then_y()为例

++z不被执行的唯一可能情况是x == true && y == false,而一旦x为true,read_y_t ...

Thanks for your answer. I understand it now.:)
页: [1]
查看完整版本: C++ atom question