std::atomic<int> x(0);
讓我們假設我有一個函數執行以下操作:
int x_old = x.fetch_add(1,std::memory_order_acq_rel);
基礎上description for acquire release memory ordering:
memory_order_relaxed操作輕鬆:沒有同步或排序約束,只有原子性需要此操作的(見下文鬆散排序)
memory_order_consume與此存儲器順序加載操作執行對受影響的存儲器位置的消費操作:沒有讀取或在當前線程依賴於當前加載的值可以寫入在此負載之前重新排序。在釋放相同原子變量的其他線程中寫入數據相關變量在當前線程中可見。只有在大多數平臺上,這會影響編譯器優化(參見發佈-消耗以下的訂購)
memory_order_acquire加載操作與此內存順序執行對受影響的存儲位置獲取操作:無閱讀或在當前線程寫入能在此負載之前重新排序。在其他線程的所有寫入該版本的相同的原子變量是在當前線程可見(見發佈 - 採集以下的訂購)
memory_order_release這種記憶順序的存儲操作執行釋放操作:無讀取或寫入當前線程可以在該商店之後重新排序。當前線程中的所有寫操作在獲取相同原子變量的其他線程中都可見(請參見下面的Release-Acquire命令),並且在原子變量中攜帶依賴項的寫入在使用相同原子的其他線程中變爲可見(請參閱Release-Consume訂購如下)。
memory_order_acq_rel該存儲器命令的讀取 - 修改 - 寫入操作既是獲取操作又是釋放操作。在當前線程中沒有內存讀取或寫入可以在該存儲之前或之後重新排序。在其他線程中釋放相同原子變量的所有寫操作在修改之前都是可見的,並且修改在獲取相同原子變量的其他線程中可見。
memory_order_seq_cst與此存儲器順序兩者獲取操作和釋放操作,加上單個總訂單存在其中所有線程觀察以相同的順序的所有修改(見下文按順序一致的排序)
的任何操作
2個不同的線程可能接收相同的x_old
值0嗎?或者他們是否保證以x_old
爲0的方式執行其中的一個,而另一個是1。
如果x_old
對於它們兩個都可能爲0,那麼更改內存順序爲std::memory_order_seq_cst
是否保證x_old
的唯一性?
內存排序不相關。兩個線程不可能獲得相同的值(假設每個線程只能達到一次表達式)。 – 2501
內存排序爲什麼不重要?難道兩個線程都不能在acq_rel下獲得相同的x_old,因爲讀取 - 修改 - 寫入操作沒有讀取讀取順序? –
訂購在這裏根本就不相關。從fetch_add返回的前兩個值始終爲:0和1,但不能保證哪個線程獲得哪個值。無論您選擇哪種memory_order,情況都是如此。 – 2501