在例子中:
#include <thread>
#include <atomic>
#include <cassert>
#include <vector>
std::vector<int> data;
std::atomic<int> flag = ATOMIC_VAR_INIT(0);
void thread_1()
{
data.push_back(42);
flag.store(1, std::memory_order_release);
}
void thread_2()
{
int expected=1;
while (!flag.compare_exchange_strong(expected, 2, std::memory_order_acq_rel)) {
expected = 1;
}
}
void thread_3()
{
while (flag.load(std::memory_order_acquire) < 2)
;
assert(data.at(0) == 42); // will never fire
}
int main()
{
std::thread a(thread_1);
std::thread b(thread_2);
std::thread c(thread_3);
a.join(); b.join(); c.join();
}
1- 如果我用 std::memory_order_acquire 替换 thread_2 中的 std::memory_order_acq_rel,我是否仍能保证 thread_3 中的断言永远不会触发?
2 - std::memory_order_release 能否使用 std::memory_order_acquire 与 2 个线程同步(如果 2 个线程正在监视具有获取语义的同一标志)?
最佳答案
您在线程 2 中没有要同步的内容,因此 std::memory_order_relaxed 内存排序在这里更为合理。
变量
x
的 std::memory_order_release 标记存储与变量x
的 std::memory_order_acquire 标记加载同步,甚至初始存储后跟序列x
上的原子读取-修改-写入操作
关于c++ - 获取/释放内存顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21272691/