3 回答

TA貢獻(xiàn)1843條經(jīng)驗(yàn) 獲得超7個贊
問題中的更新的1代碼( 在線程4中進(jìn)行了裝載x和y交換)實(shí)際上測試了所有線程是否同意全局存儲順序。
在C ++ 11內(nèi)存模型下,結(jié)果r1==1, r2==0, r3==2, r4==0是允許的,實(shí)際上在POWER上是可觀察的。
在x86上,這種結(jié)果是不可能的,因?yàn)樵谀抢铩捌渌幚砥饕砸恢碌捻樞蚩吹酱鎯Α薄T陧樞蛞恢聢?zhí)行中也不允許此結(jié)果。
注:1:這個問題原本有兩個讀者閱讀x,然后y。甲順序一致的執(zhí)行是:
-- Initially --
std::atomic<int> x{0};
std::atomic<int> y{0};
-- Thread 4 --
int r3 = x.load(std::memory_order_acquire);
-- Thread 1 --
x.store(1, std::memory_order_release);
-- Thread 3 --
int r1 = x.load(std::memory_order_acquire);
int r2 = y.load(std::memory_order_acquire);
-- Thread 2 --
y.store(2, std::memory_order_release);
-- Thread 4 --
int r4 = y.load(std::memory_order_acquire);
結(jié)果是r1==1, r2==0, r3==0, r4==2。因此,這根本不是一個奇怪的結(jié)果。
為了說每個讀者看到的商店順序不同,我們需要他們以相反的順序閱讀,以排除最后一個商店只是被延遲了。

TA貢獻(xiàn)1817條經(jīng)驗(yàn) 獲得超6個贊
是怪異的結(jié)果 r1==1, r2==0,并r3==0, r4==2有可能在C ++ 11內(nèi)存模型下,這種情況下?
是。C ++內(nèi)存模型允許這種奇怪的結(jié)果。
如果我要全部替換std::memory_order_acq_rel成該std::memory_order_relaxed怎么辦?
如果更換所有memory_order_acquire和memory_order_release通過memory_order_relaxed,沒有什么改變你的代碼。
std::memory_order_seq_cst就像,std::memory_order_acq_rel但是std::memory_order_acquire-loads在std::memory_order_release-writes 之前可能不會移動。我看不到上面示例中的此附加約束如何防止出現(xiàn)奇怪的結(jié)果。
“ acquire-load可能不會在release-writes 之前移動?!?顯示了順序一致性約束(memory_order_seq_cst)的一方面。
在C ++內(nèi)存模型中,它僅保證seq_cst具有acq_rel語義,并且所有 seq_cst原子訪問不會多多少少都具有“總順序”。當(dāng)存在這樣的“總順序”時,我們無法得到怪異的結(jié)果,因?yàn)樗衧eq_cst原子訪問都好像在單個線程上以任何交錯順序執(zhí)行一樣。
您先前的問題對待單個原子變量的“一致性” ,而這個問題要求所有原子變量的“一致性” 。C ++內(nèi)存模型可確保單個原子變量甚至最弱的排序()的直觀一致性relaxed,以及不同原子變量的“順序一致性”,只要默認(rèn)排序(seq_cst)。seq_cst如您所指出的那樣,當(dāng)您使用顯式無序原子訪問時,這可能是奇怪的結(jié)果。
- 3 回答
- 0 關(guān)注
- 575 瀏覽
添加回答
舉報