我想我很了解C++原子库中各种C++标志的语义。
但是,我对以下情况感到困惑:
假设我们有两个线程--线程A (“主执行”线程)和线程B (线程B),线程B是线程池的一部分,可以调度和运行任务。
如果我使用std::memory_order_acq_rel执行“读-写-更新”原子操作,那么对布尔变量执行非原子写入,其他线程会立即看到非原子写入吗?我认为答案是否定的,除非其他线程也访问执行“读-写-更新”操作的原子变量。
例如,给定一个全局std::atomic_flag变量X、一个全局bool值B和一个具有成员函数dispatch的线程池对象THREADPOOL,该对象将在另一个线程中执行任意函数处理程序:
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?
});
}因此,在本例中,lambda函数中的代码将在不同的线程中执行。该线程是否一定要看到第一个线程中对B的(非原子性)更新?请注意,第二个线程不访问atomic_flag,因此我的理解是,在第二个线程中不一定会看到对B的更改。
我的理解对吗?如果是这样的话,使用std::memory_order_seq_cst会改变这一点吗?
发布于 2015-06-29 19:44:51
dispatch方法在THREADPOOL中的正确实现应该提供调用方在此方法调用之前执行的所有操作与传递给该方法的函数(在您的示例中为lambda)执行的所有操作之间的happens-before关系。
因此,执行lambda函数的辅助线程肯定会看到由主线程分配的B值。
没有发生-在顺序之前,确保变量修改的可见性的唯一方法是使用std::memory_order_seq_cst进行修改和读取。参见,例如,this question。
发布于 2015-06-29 18:21:30
没有内存顺序规范使未来的内存访问可见。充其量,它们可以防止它们在原子访问可见之前变得可见。
如果要确保特定访问确实可见,则必须对该访问强制执行特定的内存排序,或者必须具有使用内存排序的未来访问权限,以确保在要使访问可见后对其进行排序。
所有原子操作都是原子操作。内存排序只允许您做三件事:
所有这些都不能确保未来的非原子操作“很快”发生或在任何特定时间变得可见。
https://stackoverflow.com/questions/31121876
复制相似问题