我有一個問題,我需要能夠自動更新兩個uint64_t
的同時。很容易以原子方式編寫它們中的每一個(例如,有兩個std::atomic<uint64_t>
),但這仍然會導致一個更新但另一個不更新的情況。使用鎖和互斥鎖也很容易。你能原子地寫兩個uint64_t嗎?
但是我想同時寫入,沒有任何類型的鎖,這樣我仍然可以使用類型爲uint64_t
的成員變量,以便讀取時不會鎖定。這是因爲我的用例涉及很多很多次的閱讀,但是很少寫(〜讀1x/ms,寫1x/5分鐘)。可能嗎?如果是這樣,怎麼樣?
我有一個問題,我需要能夠自動更新兩個uint64_t
的同時。很容易以原子方式編寫它們中的每一個(例如,有兩個std::atomic<uint64_t>
),但這仍然會導致一個更新但另一個不更新的情況。使用鎖和互斥鎖也很容易。你能原子地寫兩個uint64_t嗎?
但是我想同時寫入,沒有任何類型的鎖,這樣我仍然可以使用類型爲uint64_t
的成員變量,以便讀取時不會鎖定。這是因爲我的用例涉及很多很多次的閱讀,但是很少寫(〜讀1x/ms,寫1x/5分鐘)。可能嗎?如果是這樣,怎麼樣?
我不認爲有可能直接做,但你可以做的是使用software transactional memory techniques來僞造它。尤其是,您可以使用uint64_t對的無鎖環形緩衝區。在這種配置下,寫入環形緩衝區的非活動元素是非安全的,因爲沒有人會從環形緩衝區的那個元素讀取,直到「當前值索引」被原子更新爲寫入結束(這可能是因爲索引可以是int32_t)。
注意事項:如果您可以保證在短時間內不會有太多的寫入值(其中'太多'表示'超過環中的插槽數量'緩衝)。另外,我建議找到一個實現這個功能的STM庫,而不是自己動手編寫,因爲無鎖編程出人意料地很難100%正確。
爲什麼不創建一個類的兩個uint64_t中的,並用它來與的std ::原子
class atomic128 {
uint64_t a1, a2;
};
,然後只用std::atomic<atomic128>
另一種辦法是使用SSE加載/存儲
編輯:
爲了對某些用戶定義的UDT使用
std::atomic<UDT>
,此typ e必須有一個簡單的複製分配操作符。
這個名字就是一個例子,它不是很重要。 OP應該決定最能反映他的工作的那個。無論如何,我只是編輯了答案 –
-1在任意類型上實例化原子「
但是,請注意,對'std :: atomic
嗯....聽起來像你正在尋找在錯誤的類型鎖定模式,或許。 –
C++不可能。如果您使用的是x64 CPU,則可以使用「CMPXCHG16B」指令,如果兩個64位值是並排和16字節對齊的。 –
您可以無鎖地訪問的對象取決於硬件。如果硬件不支持128位原子對象,那麼你根本無法做到。原子模板是抽象出這種差異的方法,在需要硬件的硬件上使用鎖定,並在可用硬件支持的情況下使用鎖定。 – bames53