簡體   English   中英

標准::map <int, std::bitset<256> > 沒有互斥量的線程安全?</int,>

[英]std::map<int, std::bitset<256 > > thread safety w/o mutex?

我有一個

std::map<int, std::bitset<256 > > m;

施工后不會插入新鑰匙,也不會移除任何鑰匙。 我可以在不使用互斥鎖的情況下在一個線程中安全地分配位集,同時在其他線程中讀取它嗎?

// thread 1: 
std::bitset<256> a = getBitset();
m[1] = a;  

// thread 2:
std::bitset<256> b = m[1]; 
// or alternatively 
std::bitset<256> c = m.at(1);

我認為該程序不會崩潰,但位集中可能會發生數據競爭。 如果讀取將提供新舊位集的組合,則數據競爭是可以接受的。

不,這不安全。

bitsetoperator=是修改操作,因此如果在另一個線程中同時訪問bitset ,則不能保證不會發生數據競爭。 在實踐中,它幾乎肯定會導致數據競爭,因為它需要寫入 object。這不是特定於std::bitset ,但對於幾乎所有非空非原子標准庫類型(和大多數其他非空類型)。

任何數據競爭都會導致未定義的行為。 沒有部分更新。 從這個意義上說,它永遠不應該被接受。

如果你希望能夠做到這一點,要么將bitset包裝在一個帶有mutexstruct中以保護對bitset的訪問,要么使用類似於 atomic shared_ptr的東西,它允許用新的 bitset 原子地交換舊的bitset並延遲銷毀舊的,直到所有引用都消失了。

雖然我認為不能保證,但std::bitset也可以很容易地復制。 您可以使用std::is_trivially_copyable_v上的static_assert進行檢查,如果為true ,您還可以使用std::atomicstd::atomic_ref這將允許以原子方式訪問位集(即沒有數據競爭)並且可能會使用鎖僅當底層架構不支持對相應大小的 object 的原子訪問時。

還要注意std::bitset b = m[1]; 並且m[1]也會導致未定義的行為,因為std::mapoperator[]也是修改操作,並且未指定為沒有數據競爭,即使它沒有將新元素插入 map . 您需要使用例如find()成員 function 來代替。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM