簡體   English   中英

std :: atomic bool變量的訪問順序

[英]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::mutextry_lock()方法。 請參閱std :: mutex文檔

現在,為什么您的代碼無法按預期工作:簡化一下std :: atomic可以確保在並行訪問變量時不會出現數據爭用。 即有一個定義明確的讀寫順序。 這不足以滿足您的要求。 試想一下if分支:

if(!executing) {
   executing = true;

請記住,只有executing的讀寫操作是原子的。 至少留下了否定! if本身不同步。 有兩個線程,執行順序可能是這樣的:

  1. 線程1讀取executing (原子上),值為false
  2. 線程1否定從executing讀取的值,value = true
  3. 線程1評估條件並進入分支
  4. 線程2讀取executing (原子上),值為false
  5. 線程1組executing為true
  6. 線程2取反了該值,該值被讀取為false,現在又變為true
  7. 線程2進入分支...

現在兩個線程都進入了分支。

我會根據以下建議提出建議:

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.

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