[英]is multiple assignments of atomic variables, an atomic operation?
考慮我有兩個原子布爾值如下。
private:
std::atomic_bool x;
std::atomic_bool y;
我可以說下面的操作是原子的嗎? 還是我必須使用lock_guard
來確保它們被分配在一起?
x = y = true; // are two bools assigned together atomically?
還考慮在另一個線程中我想閱讀這些布爾值。
if(!x && !y) ...
我的假設是這不是原子的,也許最好改用atomic<int>
?
不它不是。 原子操作所保證的只是變量上不會發生任何干預操作。 在您的示例中,完全有可能y
被分配,一些不相關的事情發生(但僅在另一個線程中;在當前線程中,由於operator=
在原子上隱含的內存柵欄,不會發生重新排序),然后x
得到分配。 閱讀它們時也是如此。
如果你真的希望這些操作是原子的,你需要使用一個單一的原子類型來封裝這兩條信息。 有很多方法可以做到這一點; 您可以使用 char 並以一些位屏蔽操作為代價利用不同的位,您可以使用 16 位整數,但我將使用最清晰的(恕我直言)方法進行說明:具有兩個布爾值的結構。
struct MyBools {
bool x;
bool y;
};
bool operator==(const MyBools& lhs, const MyBools& rhs) {
return lhs.x == rhs.x && lhs.y == rhs.y;
}
using MyAtomicBools = std::atomic<MyBools>;
MyAtomicBools b{true, true};
...
if (b == MyBools{false, false}) { ... }
這可能會也可能不會優化以及使用 16 位整數並手動丟棄兩個布爾值。 gcc 似乎對此進行了非常好的優化; 它將設置操作變成單個寫入 + 內存柵欄,但 clang 效果不佳: https ://godbolt.org/g/moiT9Y。
x = y = true; // are two bools assigned together atomically?
該行顯然不是原子操作,因為 x 和 y 位於內存中的兩個不同位置:不可能同時設置兩個不連續的位置³。
原子詞意味着讀取或寫入在一個 cpu 周期內完成¹,因此一個變量是安全的,但 x 和 y 是兩個不同的原子變量。
如果您有任何疑問,請不要猶豫,通過使用反匯編程序查看生成的二進制代碼。
if(!x && !y) ...
相同:CPU 必須通過將值復制到它自己的寄存器中來訪問兩個不同變量的值,進行布爾求值,求反,然后執行求值²; 顯然不是原子操作。
¹ 它肯定不是那么簡單,但是從高級語言開發人員的角度來看,您應該認為
² 又不是那么簡單,因為編譯器可以進行優化,而 CPU 可以自己做一些事情
³ 即使有連續的位置,總大小也必須在一個循環中可讀/可寫:1Mo 的數據顯然不能在一個循環中被 cpu 讀取,即使所有數據都是連續並排的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.