c++ - c++11(atomic)的获取释放操作

标签 c++ multithreading c++11

#include <atomic>
#include <iostream>
#include <thread>

class atomicAcquireRelease00
{
public:
    atomicAcquireRelease00() : x(false), y(false), z(0) {}
    void run()
    {
        std::thread a(&atomicAcquireRelease00::write_x, this);
        std::thread b(&atomicAcquireRelease00::write_y, this);
        std::thread c(&atomicAcquireRelease00::read_x_then_y, this);
        std::thread d(&atomicAcquireRelease00::read_y_then_x, this);

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

        std::cout<<"z == "<<z.load()<<std::endl;
    }

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

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

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

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

    }

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

int main()
{
   for(size_t i = 0; i != 50; ++i){
     atomicAcquireRelease00().run();
   }          

  return 0;
}

atomicAcquireRelease00加载值时不遵守顺序。作为 据我所知,如果我将操作商店声明为 std::memory_order_release 和操作负载为 std::memory_order_acquire作为一对,操作 在同一个原子变量上加载和存储将同步,但这很简单 示例未按预期运行。

基于我想象的过程

  • 案例 A:

    1. x 设为真
    2. 在(4)处,y.load返回false,z保持为零
    3. y 设为真
    4. (6)后z变成1
  • 案例 B:

    1. y 设为真
    2. 在(6)处,x.load返回false,z保持为零
    3. x 设为真
    4. (4)后z变成1
  • 案例 C:

    1. x 设为真,y 设为真
    2. 经过(4)和(6)后,z变为2

我不能保证xy将首先设置为真,但是当x设置为真,加载x应该与它同步以及y,那么什么样的情况会使z保持零?

最佳答案

正是 Anthony Williams 的“Concurrency In Action”中的示例 list 5.7。

他解释说:

In this case the assert can fire (just like in the relaxed-ordering case), because it’s possible for both the load of x and the load of y to read false. x and y are written by different threads, so the ordering from the release to the acquire in each case has no effect on the operations in the other threads.

enter image description here

关于c++ - c++11(atomic)的获取释放操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18677139/

相关文章:

c++ - x 时间后如何中止 Winsock 连接

c++ - 为什么 VS2015 中模板相关的嵌套类型名称不需要 typename 关键字?

c++ - 在字符串C++中的字符之间添加空格

c++ - 在继承层次结构中将接口(interface)与实现分离(C++ 新手)

c++ - 为什么对数组的 const 左值引用不在下面编译?

c++ - 为什么我不能使用 chrono 库?

c++ - 使用boost::thread的Actor计算模型

c++ - 如何根据一本书的段落创建思维导图

c++ - 在qt中更改svg的颜色

multithreading - EnumWindows 和 EnumChildWindows 使我的 Treeview 保持更新