[英]access order of std::atomic bool variable
我有一個訪問(讀取和寫入) std::atomic<bool>
變量的函數。 我試圖了解指令的執行順序,以便確定atomic是否足夠,或者我必須在這里使用互斥體。 功能如下:
// somewhere member var 'executing' is defined as std::atomic<bool>`
int A::something(){
int result = 0;
// my intention is only one thread should enter next block
// others should just return 0
if(!executing){
executing = true;
...
// do some really long processing
...
result = processed;
executing = false;
}
return result;
}
我已經閱讀了有關cppreference的頁面 ,其中提到-
std :: atomic模板的每個實例化和完全專業化都定義了一個原子類型。 如果一個線程寫入一個原子對象,而另一個線程讀取一個原子對象,則行為是明確定義的(有關數據競爭的詳細信息,請參閱內存模型)
在“內存模型” 頁面上 ,提到了以下內容-
當一個表達式的評估值寫入一個存儲位置,而另一個評估值讀取或修改相同的存儲器位置時,這些表達式就會發生沖突。 評估有兩個沖突的程序會發生數據爭用,除非其中任何一個
這兩個相互矛盾的評估都是原子操作(請參閱std :: atomic)
發生沖突的評估之一發生在另一評估之前(請參閱std :: memory_order)
如果發生數據爭用,則程序的行為是不確定的。
略低於它的內容是-
當線程從內存位置讀取值時,它可能會看到初始值,寫在同一線程中的值或寫在另一個線程中的值。 有關從線程進行的寫入對其他線程可見的順序的詳細信息,請參見std :: memory_order。
這對我來說有點令人困惑,上面這3條語句中的哪一條實際上在發生?
當我執行if(!executing){
,這條指令是原子指令嗎? 更重要的是-是否保證沒有其他線程會進入if循環,如果有兩個線程將進入if循環,因為第一個線程將executing
設為true
?
如果上述代碼有問題,我應該如何重寫它,以使其反映出最初的意圖。
如果我理解正確,則您正在嘗試確保只有一個線程將同時執行一段代碼。 這正是互斥量所做的。 由於您提到過如果互斥鎖不可用,您不希望線程阻塞,所以您可能想看看std::mutex
的try_lock()
方法。 請參閱std :: mutex的文檔 。
現在,為什么您的代碼無法按預期工作:簡化一下std :: atomic可以確保在並行訪問變量時不會出現數據爭用。 即有一個定義明確的讀寫順序。 這不足以滿足您的要求。 試想一下if分支:
if(!executing) {
executing = true;
請記住,只有executing
的讀寫操作是原子的。 至少留下了否定!
和if
本身不同步。 有兩個線程,執行順序可能是這樣的:
executing
(原子上),值為false executing
讀取的值,value = true executing
(原子上),值為false executing
為true 現在兩個線程都進入了分支。
我會根據以下建議提出建議:
std::mutex myMutex;
int A::something(){
int result = 0;
// my intention is only one thread should enter next block
// others should just return 0
if(myMutex.try_lock()){
...
// do some really long processing
...
result = processed;
myMutex.unlock();
}
return result;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.