簡體   English   中英

原子變量的多次賦值是原子操作嗎?

[英]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.

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