std::atomic<int> cnt = {2};
thread 1:
doFoo();
if (cnt.fetch_sub(1, std::memory_order_relaxed) == 1) {
doBazz();
}
thread 2:
doBar();
if (cnt.fetch_sub(1, std::memory_order_relaxed) == 1) {
doBazz();
}
我们可以保证
doFoo()
和doBar()
总是在doBazz()
之前发生吗? 最佳答案
您显示的代码中根本没有内存排序,因此保证不成立。但是,可以通过使fetch_sub
成为release sequence的一部分来使用宽松的排序方式并使其正常工作:
std::atomic<int> cnt{0};
cnt.store(2, std::memory_order_release); // initiate release sequence (RS)
//thread 1:
doFoo();
if (cnt.fetch_sub(1, std::memory_order_relaxed) == 1) { // continue RS
std::atomic_thread_fence(std::memory_order_acquire); // synchronizes with RS
doBazz();
}
//thread 2:
doBar();
if (cnt.fetch_sub(1, std::memory_order_relaxed) == 1) { // continue RS
std::atomic_thread_fence(std::memory_order_acquire); // synchronizes with RS
doBazz();
}
或者
void doBazz();
std::atomic<int> cnt{0};
cnt.store(2, std::memory_order_release); // initiate release sequence (RS)
//thread 1:
doFoo();
if (cnt.fetch_sub(1, std::memory_order_relaxed) == 1) { // continue RS
doBazz();
}
//thread 2:
doBar();
if (cnt.fetch_sub(1, std::memory_order_relaxed) == 1) { // continue RS
doBazz();
}
void doBazz() {
std::atomic_thread_fence(std::memory_order_acquire); // synchronizes with RS
// ...
}
这些保证
doFoo()
和doBar()
始终在doBazz()
之前发生。关于c++ - fetch_sub与memory_order_relaxed的原子引用计数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38448886/