あなたが示したコードではメモリの順序は全くないため、保証はではなく、が成立します。しかし、あなたがいるとそれが動作していどこrelease sequenceのfetch_sub
一部を行うことで、リラックスした順序付けを使用することが可能である:
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()
前に起きていることこれらの保証。でも緩和メモリモデルと、外の薄い空気の値が最初にxとyはゼロで、例えば、円独自の計算に依存することが許可されていない
memory_order_relaxedを使用しています。つまり、メモリの順序付けが実行されていません。そのような保証はありません。 – 2501