我正在观看 Herb Sutter 的演讲:https://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Herb-Sutter-atomic-Weapons-2-of-2
看两个例子(大约 1:15 分),一个对我来说有意义,另一个对我来说没有意义。
第一个例子(有意义):
注意 count
是一个原子整数。
在这里,使用宽松的内存顺序进行加载/存储计数被认为是可以的,因为线程退出发生在从线程上的连接返回之前。这意味着松弛添加发生在松弛加载之前。
子线程:
while (...) {
if (...) {
count.fetch_add(1, memory_order_relaxed);
}
}
主线程:
int main() {
launch_workers();
join_workers();
cout << count.load(memory_order_relaxed);
}
第二个例子(不清楚):
注意 dirty
和 stop
是原子 bool 值。
这里,讲的是dirty
上的store和load必须分别使用release和acquire排序,因为dirty
是用来发布一些被读取用于清理的数据.
子线程:
while(!stop.load(memory_order_relaxed)) {
if (...) {
// publish some data
dirty.store(true, memory_order_release)
}
}
主线程:
int main() {
launch_workers();
stop = true;
join_workers();
if (dirty.load(memory_order_acquire)) {
// read published data to clean up
}
}
我的问题是,在第二个示例中,为什么不能在线程退出和从线程的连接返回之间应用相同的“先于发生”关系来同步内存?
我认为它可以在 dirty
的操作上使用宽松的内存顺序的方式是:
[子线程做一些工作,包括发布数据]
[子线程退出] -(发生在之前)-> [从 join_workers()
调用中的子线程加入返回]
[主线程都将 dirty
视为 true 并且可以安全地读取已发布的数据以进行清理]
最佳答案
大约 1 点 17 分 25 秒,他说“现在,因为你碰巧知道我通过加入线程获得了一个发布-获取,我已经在其中注入(inject)了一个发布-获取;这可能已经足够好了并且你可以去放松”。所以他似乎在说,最后,如果以宽松的内存顺序访问 dirty
实际上没问题。
关于c++ - 如果中间有线程连接,为什么不能使用宽松的原子操作来同步内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64381415/