FreeOZ论坛

标题: C++ atom question [打印本页]

作者: DDD888    时间: 30-6-2016 20:34
标题: C++ atom question
I don't understand why z.load() show value 2.

Can you explain the idea to me?

Thanks in advance

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 23:58
因为x和y都是true,所以++z执行了两次?
作者: DDD888    时间: 1-7-2016 07:28
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 22:17
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 07:13
clarkli 发表于 1-7-2016 21:17
所以看缘分,我在VM里面跑的结果大部分是1,偶尔是2

That is strange. I always got 2
作者: clarkli    时间: 2-7-2016 13:41
和操作系统线程调度有关。
换台电脑,或者换个系统结果可能就不一样了。这个代码是不能在生产中用的
作者: DDD888    时间: 2-7-2016 17:12
本帖最后由 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
#include <atomic>
#include <thread>
#include <iostream>
#include <assert.h>

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

void
thread_1()
{
        data[0].store(42, std::memory_order_relaxed);
        data[1].store(97, std::memory_order_relaxed);
        data[2].store(17, std::memory_order_relaxed);
        data[3].store(-141, std::memory_order_relaxed);
        data[4].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[0].load(std::memory_order_relaxed) == 42);
        assert(data[1].load(std::memory_order_relaxed) == 97);
        assert(data[2].load(std::memory_order_relaxed) == 17);
        assert(data[3].load(std::memory_order_relaxed) == -141);
        assert(data[4].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 19:45
DDD888 发表于 2-7-2016 16:12
The trouble for me is that I do not understand that source code.

I understand following code  ...

不理解为什么输出2还是不理解为什么那样写?
作者: DDD888    时间: 3-7-2016 19:54
clarkli 发表于 3-7-2016 18:45
不理解为什么输出2还是不理解为什么那样写?

不理解为什么输出2
作者: clarkli    时间: 4-7-2016 00:13
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 10:08
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 22:11
不会,++z至少会被执行一次
作者: DDD888    时间: 5-7-2016 09:20
clarkli 发表于 4-7-2016 21:11
不会,++z至少会被执行一次

Why?
作者: clarkli    时间: 5-7-2016 21:08
以read_x_then_y()为例

  1. while (!x.load(std::memory_order_acquire));
  2.    
  3. if (y.load(std::memory_order_acquire)) {
  4.     ++z;
  5. }
复制代码

++z不被执行的唯一可能情况是x == true && y == false,而一旦x为true,read_y_then_x()中的++z就必然会被执行。因此++z至少被执行一次。
作者: DDD888    时间: 6-7-2016 07:10
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.




欢迎光临 FreeOZ论坛 (https://www.freeoz.org/bbs/) Powered by Discuz! X3.2