所以我開始熟悉C++ 11 <atomic>
類型。在過去,當我有一個原子標記時,我通常會在訪問它之前鎖定一個互斥鎖。一個常見的需求是檢查標誌是否爲false
,如果是,自動將其設置爲true
然後執行某些操作。所以基本上這將是這樣來完成,其中flag
是一個簡單的bool
:std :: atomic原理的基本用法<T>
{
std::lock_guard<std::mutex> lock(my_mutex);
if (!flag)
{
flag = true;
// do something;
}
}
所以,現在我想弄清楚是怎麼一回事可以<atomic>
來完成。 docs表示原子類型的賦值運算符和operator T
是原子操作。但是,如果我改變flag
到std::atomic<bool>
,我想我不能簡單說:
if (!flag)
{
flag = true;
// do something
}
...因爲即使表達(!flag)
是原子,並分配flag = true
是原子的,沒有什麼可以阻止另一個線程從修改這兩條語句之間的標誌。
所以,如果我理解正確的話在這裏,唯一的正確用法 - 在所有 - 用原子類型,其中有條件的結果可以修改原子變量條件句,是使用比較和交換操作?我對麼?
所以,我不得不說:
bool expected = false;
if (flag.compare_exchange_weak(expected, true))
{
// do something
}
我是在我的理解正確嗎?
['std :: atomic_flag'](http://en.cppreference.com/w/cpp/atomic/atomic_flag)存在於您正在描述的用例中,而且更確切地說它是鎖定的,在所有平臺上免費。你可以使用'test_and_set'方法,它是原子的。你也可以使用'std :: atomic'並在其上執行一個'fetch_add',它是原子的,在增量完成時會給你以前的值(在大多數體系結構中這通常比CAS更快,儘管我想不會比'std :: atomic_flag'更快,在這種情況下這將是我的首選)。 –
Cameron
2014-10-30 15:31:19
對 - 但似乎沒有辦法簡單地原子地「檢查」原子標記的值(沒有設置它) - 或者是否存在?文檔沒有定義「運算符布爾」或任何可以啓用表達式「if(flag)」的內容。我意識到我沒有在我的問題中指定這個要求 - 我只是想知道。說到......爲什麼*不是*有辦法簡單地檢查原子標誌而不設置它? – Siler 2014-10-30 15:54:09
這是正確的,你必須設置它才能測試它(這與你當前編寫的示例代碼相同,只是它是原子的)。如果你需要獨立測試它,我建議使用'fetch_add'方法或'compare_exchange_strong'(它更清晰,並且[與x86上的'fetch_add'('lock xadd')一樣快](http:// www.agner.org/optimize/instruction_tables.pdf))。 – Cameron 2014-10-30 15:55:35