c++ - 混淆发生在并发关系之前
问题描述
下面是Concurrency in Action中给出的示例,作者说assert
可能会触发,但我不明白为什么。
#include <atomic>
#include <thread>
#include <assert.h>
std::atomic<bool> x,y;
std::atomic<int> z;
void write_x_then_y()
{
x.store(true,std::memory_order_relaxed);
y.store(true,std::memory_order_relaxed);
}
void read_y_then_x()
{
while(!y.load(std::memory_order_relaxed));
if(x.load(std::memory_order_relaxed))
++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);
}
据我所知,在每个单线程中,sequenced before
也意味着happens before
. 因此,在线程 a 中,存储x
发生在之前y
,这意味着x
应该在之前进行修改,y
并且结果x.store
应该在修改之前可见y
。
但是在这个例子中,作者说 和 之间的商店x
可以y
重新排序,为什么?这是否违反sequenced before
and的规则happens before
?
解决方案
推荐阅读
- google-apps-script - 即使其 IP 被列入白名单,UrlFetchApp 也会返回 403 响应代码?(2020 年 3 月)
- javascript - 如何使用传单标记作为 nuxt-link?
- java - 在 MVVM 中显示对话框、布局和数据过滤
- c++ - 试图要求多个可变参数类型成为特定类型
- ios - 多个文本字段的 PickerView 只显示一个数组
- angular - Angular 服务失败,因为我的源代码中没有意外字符“#”
- azure - 从 SQL Server 集成服务迁移 SSISDB - 无法从 xml 为任务 Azure Blob 下载任务创建任务
- java - 如何在 Vaadin Flow 14 中序列化和反序列化组件?
- javascript - 创建多个组件
- javascript - 如何使用lodash在内部数组包含其他对象的数组中查找对象