日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++ std::condition_variable wait() wait_for() 区别

發(fā)布時(shí)間:2024/4/18 c/c++ 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ std::condition_variable wait() wait_for() 区别 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、std::condition_variable 是條件變量。

wait()

當(dāng) std::condition_variable 對(duì)象的某個(gè) wait 函數(shù)被調(diào)用的時(shí)候,它使用 std::unique_lock(通過 std::mutex) 來鎖住當(dāng)前線程。當(dāng)前線程會(huì)一直被阻塞,直到另外一個(gè)線程在相同的 std::condition_variable 對(duì)象上調(diào)用了 notification 函數(shù)來喚醒當(dāng)前線程。

首先我們來看一個(gè)簡單的例子

#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; // 全局標(biāo)志位.void do_print_id(int id) {std::unique_lock <std::mutex> lck(mtx);while (!ready) // 如果標(biāo)志位不為 true, 則等待...cv.wait(lck); // 當(dāng)前線程被阻塞, 當(dāng)全局標(biāo)志位變?yōu)?true 之后,// 線程被喚醒, 繼續(xù)往下執(zhí)行打印線程編號(hào)id.std::cout << "thread " << id << '\n'; } void go() {std::unique_lock <std::mutex> lck(mtx);ready = true; // 設(shè)置全局標(biāo)志位為 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; }

執(zhí)行結(jié)果如下:

10 threads ready to race... thread 1 thread 0 thread 2 thread 3 thread 4 thread 5 thread 6 thread 7 thread 8 thread 9

std::condition_variable::wait() 介紹

unconditional (1)predicate (2)
void wait (unique_lock<mutex>& lck);
  • template?<class?Predicate>

  • void wait (unique_lock<mutex>& lck, Predicate pred);在第二種情況下(即設(shè)置了 Predicate),只有當(dāng) pred 條件為 false 時(shí)調(diào)用 wait() 才會(huì)阻塞當(dāng)前線程,并且在收到其他線程的通知后只有當(dāng) pred 為 true 時(shí)才會(huì)被解除阻塞。因此第二種情況類似以下代碼:

  • 當(dāng)前線程調(diào)用 wait() 后將被阻塞(此時(shí)當(dāng)前線程應(yīng)該獲得了鎖(mutex),不妨設(shè)獲得鎖 lck),直到另外某個(gè)線程調(diào)用 notify_* 喚醒了當(dāng)前線程。

    在線程被阻塞時(shí),該函數(shù)會(huì)自動(dòng)調(diào)用?lck.unlock() 釋放鎖,使得其他被阻塞在鎖競爭上的線程得以繼續(xù)執(zhí)行。另外,一旦當(dāng)前線程獲得通知(notified,通常是另外某個(gè)線程調(diào)用 notify_* 喚醒了當(dāng)前線程),wait() 函數(shù)也是自動(dòng)調(diào)用 lck.lock(),使得 lck 的狀態(tài)和 wait 函數(shù)被調(diào)用時(shí)相同。

    在第二種情況下(即設(shè)置了 Predicate),只有當(dāng) pred 條件為 false 時(shí)調(diào)用 wait() 才會(huì)阻塞當(dāng)前線程,并且在收到其他線程的通知后只有當(dāng) pred 為 true 時(shí)才會(huì)被解除阻塞。

    因此第二種情況類似以下代碼:

    while (!pred()) wait(lck);

    請(qǐng)看下面例子(參考):

    #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; }// 消費(fèi)者線程. 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); // 消費(fèi)者線程.// 主線程為生產(chǎn)者線程, 生產(chǎn) 10 個(gè)物品.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; }

    程序執(zhí)行結(jié)果如下:

    concurrency ) ./ConditionVariable-wait 1 2 3 4 5 6 7 8 9 10

    wait_for()

    std::condition_variable::wait_for() 介紹

    unconditional (1)predicate (2)
  • 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 可以指定一個(gè)時(shí)間段,在當(dāng)前線程收到通知或者指定的時(shí)間 rel_time 超時(shí)之前,該線程都會(huì)處于阻塞狀態(tài)。而一旦超時(shí)或者收到了其他線程的通知,wait_for 返回,剩下的處理步驟和 wait() 類似。

    另外,wait_for 的重載版本(predicte(2))的最后一個(gè)參數(shù) pred 表示 wait_for 的預(yù)測條件,只有當(dāng) pred 條件為 false 時(shí)調(diào)用 wait() 才會(huì)阻塞當(dāng)前線程,并且在收到其他線程的通知后只有當(dāng) pred 為 true 時(shí)才會(huì)被解除阻塞,因此相當(dāng)于如下代碼:

    return wait_until (lck, chrono::steady_clock::now() + rel_time, std::move(pred));

    請(qǐng)看下面的例子(參考),下面的例子中,主線程等待 th 線程輸入一個(gè)值,然后將 th 線程從終端接收的值打印出來,在 th 線程接受到值之前,主線程一直等待,每個(gè)一秒超時(shí)一次,并打印一個(gè) ".":

    #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; }

    總結(jié)

    以上是生活随笔為你收集整理的C++ std::condition_variable wait() wait_for() 区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。