簡單來說: 有任何Thread間的數據依賴,應該使用比relaxed更強的內存序 例如: acq_rel 和 seq_cst
acq_rel 在某些架構上(如x86)的release幾乎無開銷
以下用一個經典的例子來展示 memory_order_acq_rel 和 memory_order_seq_cst 的關鍵區別:
// seq_cst 适合的场景:需要严格顺序的多线程操作
std::atomic<bool> x{false}, y{false};
std::atomic<int> z{0};
void thread1() {
x.store(true, std::memory_order_seq_cst);
if (y.load(std::memory_order_seq_cst)) {
z.fetch_add(1, std::memory_order_seq_cst);
}
}
void thread2() {
y.store(true, std::memory_order_seq_cst);
if (x.load(std::memory_order_seq_cst)) {
z.fetch_add(1, std::memory_order_seq_cst);
}
}
// Thread 1 // Thread 2
x.store(true) y.store(true)
y.load() x.load()
可能的 seq_cst 執行順序:
1. x.store -> y.store -> y.load -> x.load (Thread 1 看到 y=true)
2. y.store -> x.store -> y.load -> x.load (Thread 2 看到 x=true)
3. x.store -> y.load -> y.store -> x.load
4. y.store -> x.load -> x.store -> y.load
但不可能同時出現:
Thread 1: 看到 y=false
Thread 2: 看到 x=false
在 seq_cst 下,z 至少會增加一次。而在 acq_rel 下,因為沒有全序的保證,可能兩個線程都看不到對方的寫入。
