首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >获取c++11(原子)的释放操作

获取c++11(原子)的释放操作
EN

Stack Overflow用户
提问于 2013-09-07 19:36:13
回答 2查看 730关注 0票数 5
代码语言:javascript
复制
#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:

代码语言:javascript
复制
1. x set as true
2. at (4), y.load return false, z remain zero
3. y set as true
4. after (6), z become one

  • 案例B:

代码语言:javascript
复制
1. y set as true
2. at (6), x.load return false, z remain zero
3. x set as true
4. after (4), z become one

  • 案例C:

代码语言:javascript
复制
1. x set as true, y set as true
2. after (4) and (6), z become 2

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-07 19:57:16

这就是,来自安东尼·威廉姆斯的“并发性在行动中”的示例清单5.7。

他解释说:

在这种情况下,断言可以触发(就像轻松排序的情况一样),因为x的加载和y的加载都可以读取falsex和y是由不同的线程编写的,因此从发布到获取的顺序在每种情况下都不会对其他线程中的操作产生影响。

票数 9
EN

Stack Overflow用户

发布于 2013-09-08 07:37:17

除非使用seq_cst,否则C/C++11不能保证存储到不同内存位置的总顺序。因此,每个线程都可以自由地按不同的顺序查看存储。获取-发布同步没有帮助,因为它只是从执行存储的线程到执行加载的线程。如果你想玩这样的单元测试,并更好地发展你的直觉,试试CDSChecker。它是一个工具,它将向您展示C11的任何实际实现可能产生的所有行为。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18677139

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档