[英]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
在加載值時不遵守順序。 據我所知,如果我將操作存儲聲明為std::memory_order_release
並將操作加載為std::memory_order_acquire
作為一對,則加載和存儲在同一原子變量上的操作將同步,但這個簡單示例不會按照我的預期工作。
這個過程基於我的想象力
案例A:
案例B:
案例C:
我不能保證x
或y
將被設置為true第一,但是當x
設置為true,負荷x
應該與它以及同步y,
那么什么樣的情況會令z
保持為零?
這正是 Anthony Williams的“Concurrency In Action”中的示例清單5.7。
他解釋說:
在這種情況下,斷言可以觸發(就像在寬松排序的情況下一樣),因為
x
的加載和y
的加載都可能讀取為false
。 x和y由不同的線程寫入 ,因此在每種情況下從發布到獲取的排序對其他線程中的操作沒有影響。
除非使用seq_cst,否則C / C ++ 11不保證存儲到不同內存位置的總順序。 因此,每個線程都可以以不同的順序自由查看商店。 獲取 - 釋放同步沒有幫助,因為它只是從執行存儲的線程到執行加載的線程。 如果你想玩這樣的單元測試並更好地發展你的直覺,試試CDSChecker。 它是一個工具,可以向您顯示C11的任何實際實現可能產生的所有行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.