簡體   English   中英

使用std :: atomic的條件的基本用法<T>

[英]Basic usage of conditionals with std::atomic<T>

所以我開始熟悉C ++ 11 <atomic>類型。 在過去,當我有一個原子標志時,我通常只是在訪問它之前鎖定一個互斥鎖。 一個常見的需求是檢查標志是否為false ,如果是,則自動將其設置為true然后執行某些操作。 所以基本上這將是這樣完成的,其中flag是一個簡單的bool

{
    std::lock_guard<std::mutex> lock(my_mutex);
    if (!flag) 
    {
        flag = true;
        // do something;
    }
}

所以,現在我想弄清楚如何用<atomic>完成同樣的事情。 文檔說原子類型的賦值運算符和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
}

我的理解是正確的嗎?

如果你有多個運行相同代碼的線程需要進行翻轉,是的 - 你需要使用compare_exchange_weak()compare_exchange_strong() ,因為你建議的原因(可能更喜歡強)。

但是,並不是說這是使用原子的條件的唯一正確用法。 如果我有一個只讀取原子的線程和一個寫入它的線程,那么以簡單的方式使用它們是完全合理的...例如:

std::atomic<bool> done{false};

// thread 1
while (!done) {
    ....
}

// thread 2
stop() { done = true; }

我沒有理由在那里做done.compare_exchange_strong(expected, true) 這太過分了。 這是真的在個案的基礎上。

是。

話雖這么說,你可能更喜歡compare_exchange_strong ,除非你處於緊張的循環中。 它可能導致性能降低,但保證能夠為您提供預期的結果( compare_exchange_weak不是)。

明顯的注意:鎖定語義與原子檢查完全不同,因為在這種情況下,另一個線程等待鎖定釋放,並且在獲取鎖定后將始終執行其操作。 因此,嚴格來說,兩個代碼示例並不相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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