#include
#include
#include <assert.h>
std::atomic x,y;
std::atomic z;
void write_x_then_y()
{
x.store(true,std::memory_order_relaxed); // 1
y.store(true,std::memory_order_relaxed); // 2
}
void read_y_then_x()
{
while(!y.load(std::memory_order_relaxed)); // 3
if(x.load(std::memory_order_relaxed)) // 4
++z;
}
int main()
{
x=false;
y=false;
z=0;
std::thread a(write_x_then_y);
std::thread b(read_y_then_x);
a.join();
b.join();
assert(z.load()!=0); // 5
}
这次assert⑤可能会触发,因为加载x的操作④可能读取到false,即使加载y的操作③读取到true,并且存储x的操作①先发与存储y的操作②。x和y是两个不同的变量,所以这里没有顺序去保证每个操作产生相关值的可见性。
以上的翻译来至于#include
#include
#include <assert.h>
std::atomic x,y;
std::atomic z;
void write_x_then_y()
{
x.store(true,std::memory_order_relaxed); // 1
y.store(true,std::memory_order_relaxed); // 2
}
void read_y_then_x()
{
while(!y.load(std::memory_order_relaxed)); // 3
if(x.load(std::memory_order_relaxed)) // 4
++z;
}
int main()
{
x=false;
y=false;
z=0;
std::thread a(write_x_then_y);
std::thread b(read_y_then_x);
a.join();
b.join();
assert(z.load()!=0); // 5
}
这次assert⑤可能会触发,因为加载x的操作④可能读取到false,即使加载y的操作③读取到true,并且存储x的操作①先发与存储y的操作②。x和y是两个不同的变量,所以这里没有顺序去保证每个操作产生相关值的可见性。
以上的翻译来至于Cpp_Concurrency_In_Action 原书的128页,
1,2位于一个函数里面
3,4位于另外一个函数里面
个人理解
read_y_then_x只能在write_x_then_y执行完成后,才能执行。这时x,y都是解锁的,也就是都是true,所以++z必然会执行.
但是作者说,存在着z=0的情况,请教一下,z=0的情况是怎么一种执行顺序呢,谢谢
如果程序死锁,那么主函数是不是就一直不能退出,那么这种情况下,z=0就没有意义了.