std :: memory_order_acq_rel对其他线程中读取的非原子变量的影响

时间:2015-06-29 17:26:38

标签: c++ multithreading c++11 atomic

我认为我主要理解C ++原子库中各种memory_order标志的语义。

但是,我对以下情况感到困惑:

假设我们有两个线程 - 线程A,它是一个“主执行”线程,而线程B,它是一个任意线程,它是线程池的一部分,可以在其中调度和运行任务。

如果我使用std::memory_order_acq_rel执行“读写更新”原子操作,则对布尔变量执行非原子写操作,非原子立即写入其他线程?我认为答案是否定的,除非其他线程也访问执行“读写更新”操作的 atomic 变量。

因此,例如,给定全局std::atomic_flag变量X,全局bool值B和具有成员函数{{的线程池对象THREADPOOL 1}},它将在另一个线程中执行任意函数处理程序:

dispatch

所以在这个例子中,lambda函数内的代码将在不同的线程中执行。该线程是否必须在第一个线程中看到if (!X.test_and_set(std::memory_order_acq_rel) { if (SOME_CONDITION) B = true; THREADPOOL.dispatch([]() { // This executes in Thread B if (B) { /* do something */ } // are we guaranteed to see changes to B? }); } 的(非原子)更新?请注意,第二个线程访问atomic_flag,所以我的理解是在第二个线程中必须看到对B的更改 not

我的理解在这里是否正确?如果是这样,会使用B更改吗?

2 个答案:

答案 0 :(得分:3)

YYYY-MM-DD中正确实现dispatch方法应该在此方法调用之前提供调用方执行的所有操作之间的THREADPOOL关系以及由此执行的所有操作函数(在你的情况下为lambda),传递给方法。

因此,执行lambda函数的辅助线程肯定会看到由主线程分配的happens-before的值。

没有发生 - 在订单之前,保证变量修改的立即可见性的唯一方法是使用B进行修改和阅读。例如,参见this question

答案 1 :(得分:2)

没有内存顺序规范使未来的内存访问可见。它们最多会阻止它们在原子访问可见之前变得可见。

如果要确保特定访问权限可见,则必须在该访问权限上强制执行特定的内存排序,或者必须具有使用内存排序的未来访问权限,以确保在要使其可见的访问权限之后对其进行排序

所有原子操作都是原子操作。内存排序只允许您做三件事:

  1. 建立与先前操作相关的原子操作的顺序,原子或非原子操作 - 保证此操作在它们之后。

  2. 针对未来的操作建立此操作的顺序,无论是否为原子 - 此操作保证在它们之前。

  3. 与其他原子操作建立排序。

  4. 这些都不能确保未来的非原子操作“很快”发生或在任何特定时间变得可见。