![](/img/trans.png)
[英]Why is there no wait function for condition_variable which does not relock the mutex
[英]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
? 如果是這樣,那是什么? 如前所述,每個調用此函數的線程都將訪問一個單獨的副本。
-編輯-
這是我為什么在此代碼中使用mutex
和condition_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.