简体   繁体   English

获取c ++ 11(原子)的发布操作

[英]Acquire release operation of c++11(atomic)

#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 do not respect the order when loading the value. atomicAcquireRelease00在加载值时不遵守顺序。 As far as I know, if I declared the operation store as std::memory_order_release and operation load as std::memory_order_acquire as a pair, the operations of load and store on the same atomic variable will synchronize, but this simple example doesn't work as I expected. 据我所知,如果我将操作存储声明为std::memory_order_release并将操作加载为std::memory_order_acquire作为一对,则加载和存储在同一原子变量上的操作将同步,但这个简单示例不会按照我的预期工作。

The process base on my imagination 这个过程基于我的想象力

  • case A : 案例A:

    1. x set as true x设为true
    2. at (4), y.load return false, z remain zero at(4),y.load返回false,z保持为零
    3. y set as true y设为真
    4. after (6), z become one 在(6)之后,z成为一个
  • case B : 案例B:

    1. y set as true y设为真
    2. at (6), x.load return false, z remain zero at(6),x.load返回false,z保持为零
    3. x set as true x设为true
    4. after (4), z become one 在(4)之后,z成为一个
  • case C : 案例C:

    1. x set as true, y set as true x设为true,y设为true
    2. after (4) and (6), z become 2 在(4)和(6)之后,z变为2

I can't guarantee x or y would be set to true first, but when x set to true, the load of x should be synchronized with it as well as y, so what kind of situation would make z remain zero? 我不能保证xy将被设置为true第一,但是当x设置为true,负荷x应该与它以及同步y,那么什么样的情况会令z保持为零?

This is exactly the Sample Listing 5.7 from "Concurrency In Action" by Anthony Williams. 正是 Anthony Williams的“Concurrency In Action”中的示例清单5.7。

He explains: 他解释说:

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的加载和y的加载都可能读取为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. x和y由不同的线程写入 ,因此在每种情况下从发布到获取的排序对其他线程中的操作没有影响。

在此输入图像描述

C/C++11 does not guarantee a total order of stores to different memory locations unless you use seq_cst. 除非使用seq_cst,否则C / C ++ 11不保证存储到不同内存位置的总顺序。 So each thread is free to see the stores in a different order. 因此,每个线程都可以以不同的顺序自由查看商店。 Acquire-release synchronization doesn't help as it is only from the thread doing the store to the thread doing the load. 获取 - 释放同步没有帮助,因为它只是从执行存储的线程到执行加载的线程。 If you want to play around with unit tests like this and better develop your intuition, try CDSChecker. 如果你想玩这样的单元测试并更好地发展你的直觉,试试CDSChecker。 It is a tool that will show you all behaviors that any real implementation of C11 is likely to produce. 它是一个工具,可以向您显示C11的任何实际实现可能产生的所有行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 c++ 释放栅栏和原子获取操作示例 - c++ release fence with atomic acquire operation example C++11中获取/释放VS顺序一致性? - Acquire/Release VS Sequential Consistency in C++11? 为什么“获取/释放”不能保证 c++11 中的顺序一致性? - Why 'acquire/release' can not guarantee sequential consistency in c++11? C ++ 11比较和交换获取/发布语义 - C++11 compare and swap acquire/release semantics C ++ 11在递增原子变量并将其赋值给其他值时,它是原子操作吗? - C++11 when increment the atomic variable, and assign it to other value, is it atomic operation? C++11 memory_order_acquire 和 memory_order_release 语义? - C++11 memory_order_acquire and memory_order_release semantics? 理解 C++11 中的 `memory_order_acquire` 和 `memory_order_release` - Understanding `memory_order_acquire` and `memory_order_release` in C++11 C ++ 11标准是否正式定义了获取,发布和使用操作? - Does the C++11 standard formally define acquire, release, and consume operations? C ++ 11是否允许(不要求)发布/获取volatile关键字的语义 - Does C++11 allow (not require) release/acquire semantics for volatile keyword 抢先式多任务处理是否可以干扰C ++ 11发行获得语义? - Could preemptive multitasking interfere with C++11 release-acquire semantics?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM