2017-07-29 78 views
4

考慮我有兩個原子布爾值如下。是原子變量的多重賦值,是一個原子操作嗎?

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>而不是?

+0

不同的問題,但有些相關:https://stackoverflow.com/questions/8858387/stdatomic-treat-a-pair-of-atomic-int32-as-one-atomic-int64 – user463035818

+0

@RickAstley我不看看如何。 'x.store'承諾分配給'x'的動作是原子的;它沒有說任何關於評估它的論點是否是原子的。它也顯然沒有道理;通過你的推理你可以存儲一個巨大函數的結果,並使整個函數成爲原子。現在你的原子變量(可能只是一個簡單的布爾)就是一個互斥體。 –

回答

4

不,事實並非如此。原子操作所保證的是,變量上不會發生干預操作。在你的例子是完全可能的,y被分配,一些不相關的情況(但只能在另一個線程,因爲operator=在原子隱含的內存圍欄在當前線程重新排序不會發生),然後x被分配。閱讀時也是如此。

如果你真的想這些操作是原子,你需要使用封裝的兩條信息一個原子類型。有很多方法可以做到這一點;你可以使用一個字符並以一些掩碼操作爲代價來使用不同的位,你可以使用一個16位的整數,但我會用最清晰的(IMHO)方法來說明:一個帶有兩個布爾值的結構。

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位整數,並且手工拋出兩個布爾值。海灣合作委員會似乎優化這個非常好;它將設置的操作變成一個單獨的寫入+內存圍欄,但是clang並不如此:https://godbolt.org/g/moiT9Y

+0

謝謝。我試圖使用原子16位整數,但這使得閱讀部分有點複雜。使用結構與描述性和個別領域是好的建議。 –

2
x = y = true; // are two bools assigned together atomically? 

即線顯然不是一個原子操作作爲x和y是在內存中的兩個不同的位置:它是不能設定未continuous³一個彼此同時兩個位置。

原子字意味着讀或寫在一個CPUcycle¹完成的,所以一個變量是安全的,但x和y是不同原子變量。

如果您有關於不要猶豫,看看產生的二進制代碼,通過使用反彙編的任何疑慮。

if(!x && !y) ... 

相同的:CPU具有通過複製值到它自己的寄存器來訪問不同變量的值,使一個布爾評價,否定,並執行evaluation² ;顯然不是原子操作。

¹它肯定是不那麼簡單,而是從一個較高的語言 developper點,你應該想到,
²這又是不是那麼簡單,因爲編譯器可以進行優化,而CPU可以使一些事情本身
³即使連續位置,總的大小必須是可讀/可寫在一個循環:1Mo鋼的數據顯然不是由CPU一個環可讀的,即使所有的數據連續地被並排設置。

+5

你對std :: atomic是什麼有一些誤解。這是一個允許編寫跨平臺原子碼的標準。 CPU寄存器或「一個循環」的大小是完全不相關的(性能除外)。另外,atomic這個詞不*表示一個CPU週期。這只是意味着它們之間沒有任何變化。僅供參考,可以使用盡可能大的類型實例化原子模板:「std :: atomic可以使用任何TriviallyCopyable類型T實例化」。 http://en.cppreference.com/w/cpp/atomic/atomic –

+0

我明白(我是C和C++開發人員),但只是簡單地解釋一下這個主題,它對我來說似乎更簡單,更接近硬件因爲原子被理解爲它的C對應物(sig_atomic_t)。 這僅僅是一個教育目的的簡化。 – lemmel