C++ std::condition_variable wait() wait_for() 区别
一、std::condition_variable 是條件變量。
wait()
當 std::condition_variable 對象的某個 wait 函數被調用的時候,它使用 std::unique_lock(通過 std::mutex) 來鎖住當前線程。當前線程會一直被阻塞,直到另外一個線程在相同的 std::condition_variable 對象上調用了 notification 函數來喚醒當前線程。
首先我們來看一個簡單的例子
#include <iostream> // std::cout #include <thread> // std::thread #include <mutex> // std::mutex, std::unique_lock #include <condition_variable> // std::condition_variablestd::mutex mtx; // 全局互斥鎖. std::condition_variable cv; // 全局條件變量. bool ready = false; // 全局標志位.void do_print_id(int id) {std::unique_lock <std::mutex> lck(mtx);while (!ready) // 如果標志位不為 true, 則等待...cv.wait(lck); // 當前線程被阻塞, 當全局標志位變為 true 之后,// 線程被喚醒, 繼續往下執行打印線程編號id.std::cout << "thread " << id << '\n'; } void go() {std::unique_lock <std::mutex> lck(mtx);ready = true; // 設置全局標志位為 true.cv.notify_all(); // 喚醒所有線程. }int main() {std::thread threads[10]; // spawn 10 threads:for (int i = 0; i < 10; ++i)threads[i] = std::thread(do_print_id, i);std::cout << "10 threads ready to race...\n";go(); // go!for (auto & th:threads)th.join();return 0; }執行結果如下:
10 threads ready to race... thread 1 thread 0 thread 2 thread 3 thread 4 thread 5 thread 6 thread 7 thread 8 thread 9std::condition_variable::wait() 介紹
| void wait (unique_lock<mutex>& lck); |
| template?<class?Predicate> void wait (unique_lock<mutex>& lck, Predicate pred);在第二種情況下(即設置了 Predicate),只有當 pred 條件為 false 時調用 wait() 才會阻塞當前線程,并且在收到其他線程的通知后只有當 pred 為 true 時才會被解除阻塞。因此第二種情況類似以下代碼: |
當前線程調用 wait() 后將被阻塞(此時當前線程應該獲得了鎖(mutex),不妨設獲得鎖 lck),直到另外某個線程調用 notify_* 喚醒了當前線程。
在線程被阻塞時,該函數會自動調用?lck.unlock() 釋放鎖,使得其他被阻塞在鎖競爭上的線程得以繼續執行。另外,一旦當前線程獲得通知(notified,通常是另外某個線程調用 notify_* 喚醒了當前線程),wait() 函數也是自動調用 lck.lock(),使得 lck 的狀態和 wait 函數被調用時相同。
在第二種情況下(即設置了 Predicate),只有當 pred 條件為 false 時調用 wait() 才會阻塞當前線程,并且在收到其他線程的通知后只有當 pred 為 true 時才會被解除阻塞。
因此第二種情況類似以下代碼:
while (!pred()) wait(lck);請看下面例子(參考):
#include <iostream> // std::cout #include <thread> // std::thread, std::this_thread::yield #include <mutex> // std::mutex, std::unique_lock #include <condition_variable> // std::condition_variablestd::mutex mtx; std::condition_variable cv;int cargo = 0; bool shipment_available() {return cargo != 0; }// 消費者線程. void consume(int n) {for (int i = 0; i < n; ++i) {std::unique_lock <std::mutex> lck(mtx);cv.wait(lck, shipment_available);std::cout << cargo << '\n';cargo = 0;} } int main() {std::thread consumer_thread(consume, 10); // 消費者線程.// 主線程為生產者線程, 生產 10 個物品.for (int i = 0; i < 10; ++i) {while (shipment_available())std::this_thread::yield();std::unique_lock <std::mutex> lck(mtx);cargo = i + 1;cv.notify_one();}consumer_thread.join();return 0; }程序執行結果如下:
concurrency ) ./ConditionVariable-wait 1 2 3 4 5 6 7 8 9 10wait_for()
std::condition_variable::wait_for() 介紹
| template<class?Rep,?class?Period> cv_status wait_for(unique_lock<mutex>& lck,?const chrono::duration<Rep,Period>& rel_time); |
| template<class?Rep,?class?Period,?class?Predicate> bool wait_for (unique_lock<mutex>& lck,?const chrono::duration<Rep,Period>& rel_time, Predicate pred); |
與?std::condition_variable::wait()?類似,不過 wait_for 可以指定一個時間段,在當前線程收到通知或者指定的時間 rel_time 超時之前,該線程都會處于阻塞狀態。而一旦超時或者收到了其他線程的通知,wait_for 返回,剩下的處理步驟和 wait() 類似。
另外,wait_for 的重載版本(predicte(2))的最后一個參數 pred 表示 wait_for 的預測條件,只有當 pred 條件為 false 時調用 wait() 才會阻塞當前線程,并且在收到其他線程的通知后只有當 pred 為 true 時才會被解除阻塞,因此相當于如下代碼:
return wait_until (lck, chrono::steady_clock::now() + rel_time, std::move(pred));請看下面的例子(參考),下面的例子中,主線程等待 th 線程輸入一個值,然后將 th 線程從終端接收的值打印出來,在 th 線程接受到值之前,主線程一直等待,每個一秒超時一次,并打印一個 ".":
#include <iostream> // std::cout #include <thread> // std::thread #include <chrono> // std::chrono::seconds #include <mutex> // std::mutex, std::unique_lock #include <condition_variable> // std::condition_variable, std::cv_statusstd::condition_variable cv; int value;void do_read_value() {std::cin >> value;cv.notify_one(); }int main () {std::cout << "Please, enter an integer (I'll be printing dots): \n";std::thread th(do_read_value);std::mutex mtx;std::unique_lock<std::mutex> lck(mtx);while (cv.wait_for(lck,std::chrono::seconds(1)) == std::cv_status::timeout) {std::cout << '.';std::cout.flush();}std::cout << "You entered: " << value << '\n';th.join();return 0; }總結
以上是生活随笔為你收集整理的C++ std::condition_variable wait() wait_for() 区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 期货品种缩写
- 下一篇: 华擎主板bios设置图解_华硕、华擎主板