簡體   English   中英

鎖定的互斥鎖是否可以保護condition_variable和數據?

[英]Does a locked mutex protect the condition_variable as well as the data?

考慮this_thread :: sleep_for()函數的以下實現。 它來自Stroustrup的書“ CPL”,第4頁,第1232頁。我已通過(i)重命名和(ii)將功能與客戶端代碼分開來對其進行了修改:

#include <chrono>       /// milliseconds
#include <mutex>        /// mutex, unique_lock
#include <condition_variable>   /// condition_variable

/// declarations ...

namespace ext
{
   void sleep_for(int ms);
}


/// implementation ...

void ext::sleep_for(int ms)
{
   std::mutex mtx;
   std::condition_variable timercv;

   /// acquire mtx
   std::unique_lock<std::mutex> lck {mtx};

   /// release and reacquire mutex
   timercv.wait_for(lck, std::chrono::milliseconds {ms});
}  // implicitly release mtx


Stroustrup指出:

互斥鎖可保護wait_for()免受數據爭用。 wait_for()在進入睡眠狀態時釋放其互斥鎖,並在其線程被解除阻塞時重新獲取它。


我想問一下:
1)通過說mutex可以保護wait_for()免受數據爭用,我假設Stroustrup指的是condition_variable本身,對嗎?

2)為什么condition_variable要求防止並發訪問? 它是局部變量,而不是全局變量。 線程對ext::sleep_for()函數的每次調用都會有condition_variable的單獨副本。

3)在此程序中,沒有要保護的全局數據(例如,就緒標志等)。 mutex是否保護condition_variable 如果是這樣,那是什么? 如前所述,每個調用此函數的線程都將訪問一個單獨的副本。

-編輯-
這是我為什么在此代碼中使用mutexcondition_variable說明:
1)需要mutex才能獲得鎖定。
2) condition_variable釋放互斥鎖,進入睡眠指定的時間段,然后重新獲取該鎖。

您的代碼中有錯誤。 條件變量被允許虛假地喚醒; 您有責任處理該案件。 上面的代碼中沒有任何東西可以處理它。 這里有一個簡單的解決方法:

timercv.wait_for(lck, std::chrono::milliseconds {ms}, []{return false;});

現在,任何早期喚醒都將被拒絕。

這仍然是條件變量的一種極其奇怪的用法。 通常,它們用於在一個或多個線程之間進行通信。 在這種情況下,互斥鎖和條件變量以及條件變量檢查的內容將形成三元組。

Stroustrup似乎在談論一個更典型的案例。

在這種更典型的情況下,互斥鎖可保護對條件變量檢查的內容的訪問,並且必須對其進行鎖定才能對條件變量執行某些操作。 由於這些是低級線程原語,因此您應該遵循有效的標准模式,或者您必須確切了解每個操作的工作以及提供的保證,並證明您的代碼正確。 任何簡化都將以“告訴孩子的謊言”的形式進行,並且基於謊言設計新的使用方式將不會具有任何可靠性。

標准中描述了確切的規格,這些是您應參考的規格。 請注意,規范在標准修訂版之間有所變化。

簡而言之,您應該找到經過驗證的使用模式並使用它們,然后封裝它們,並且永遠不要碰它們。

為睡眠寫一個更簡單的方法是:

void ext::sleep_for(int ms) {
  std::mutex mtx;
  std::unique_lock<std::mutex> lock1(mtx);
  std::unique_lock<std::mutex> lock2(mtx, std::defer_lock_t{});
  lock2.try_lock_for(std::chrono::milliseconds {ms});
}  // implicitly release mtx

它沒有一組條件那么復雜,並且使用了更簡單的原語。

暫無
暫無

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

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