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

歡迎訪問 生活随笔!

生活随笔

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

c/c++

C++11条件变量

發(fā)布時(shí)間:2025/3/20 c/c++ 12 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++11条件变量 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  • 條件變量
  • 成員函數(shù)
  • 代碼測(cè)試

條件變量

條件變量(condition variable)是利用線程間共享的全局變量進(jìn)行同步的一種機(jī)制。

包括兩個(gè)動(dòng)作:
一個(gè)線程等待某個(gè)條件為真,而將自己掛起;另一個(gè)線程使得條件成立,并通知等待的線程繼續(xù)運(yùn)行。

為了防止競(jìng)爭(zhēng),條件變量的使用總是和一個(gè)互斥鎖結(jié)合在一起。

C++11 中引入了條件變量,其相關(guān)內(nèi)容均在<condition_variable>中。
這里介紹 std::condition_variable 類。

條件變量std::condition_variable 用于多線程之間的通信,它可以阻塞一個(gè)或同時(shí)阻塞多個(gè)線程。
std::condition_variable 需要與 std::unique_lock 配合使用。
std::condition_variable 效果上相當(dāng)于包裝了 pthread 庫中的pthread_cond_*()系列的函數(shù)。

當(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)前線程。

成員函數(shù)

(1)、構(gòu)造函數(shù):僅支持默認(rèn)構(gòu)造函數(shù),拷貝、賦值和移動(dòng)(move)均是被禁用的。

(2)、wait:當(dāng)前線程調(diào)用wait()后將被阻塞,直到另外某個(gè)線程調(diào)用notify_*喚醒當(dāng)前線程;
當(dāng)線程被阻塞時(shí),該函數(shù)會(huì)自動(dòng)調(diào)用std::mutex 的unlock()釋放鎖,使得其它被阻塞在鎖競(jìng)爭(zhēng)上的線程得以繼續(xù)執(zhí)行。一旦當(dāng)前線程獲得通知(notify,通常是另外某個(gè)線程調(diào)用notify_*喚醒了當(dāng)前線程),wait()函數(shù)也是自動(dòng)調(diào)用 std::mutex 的lock()。wait 分為無條件被阻塞和帶條件的被阻塞兩種。

無條件被阻塞:調(diào)用該函數(shù)前,當(dāng)前線程應(yīng)該已經(jīng)對(duì)unique_lock<mutex> lck 完成了加鎖。所有使用同一個(gè)條件變量的線程必須在wait 函數(shù)中使用同一個(gè)unique_lock<mutex>。該wait 函數(shù)內(nèi)部會(huì)自動(dòng)調(diào)用lck.unlock()對(duì)互斥鎖解鎖,使得其他被阻塞在互斥鎖上的線程恢復(fù)執(zhí)行。使用本函數(shù)被阻塞的當(dāng)前線程在獲得通知(notified,通過別的線程調(diào)用notify_*系列的函數(shù))而被喚醒后,wait()函數(shù)恢復(fù)執(zhí)行并自動(dòng)調(diào)用lck.lock()對(duì)互斥鎖加鎖。

帶條件的被阻塞:wait 函數(shù)設(shè)置了謂詞(Predicate),只有當(dāng)pred 條件為false 時(shí)調(diào)用該wait 函數(shù)才會(huì)阻塞當(dāng)前線程,并且在收到其它線程的通知后只有當(dāng)pred 為true 時(shí)才會(huì)被解除阻塞。因此,等效于while (!pred()) wait(lck).

(3)、wait_for:與wait()類似,只是wait_for 可以指定一個(gè)時(shí)間段,在當(dāng)前線程收到通知或者指定的時(shí)間超時(shí)之前,該線程都會(huì)處于阻塞狀態(tài)。而一旦超時(shí)或者收到了其它線程的通知,wait_for 返回,剩下的步驟和wait 類似。

(4)、wait_until:與wait_for 類似,只是wait_until 可以指定一個(gè)時(shí)間點(diǎn),在當(dāng)前線程收到通知或者指定的時(shí)間點(diǎn)超時(shí)之前,該線程都會(huì)處于阻塞狀態(tài)。而一旦超時(shí)或者收到了其它線程的通知,wait_until 返回,剩下的處理步驟和wait 類似。

(5)、notify_all: 喚醒所有的wait 線程,如果當(dāng)前沒有等待線程,則該函數(shù)什么也不做。

(6)、notify_one:喚醒某個(gè)wait 線程,如果當(dāng)前沒有等待線程,則該函數(shù)什么也不做;
如果同時(shí)存在多個(gè)等待線程,則喚醒某個(gè)線程是不確定的(unspecified)。

代碼測(cè)試

條件:
10 個(gè)線程,爭(zhēng)相去打印傳入的id,第一個(gè)線程獲得鎖,但是條件不滿足,采用條件變量出讓鎖,等待條件,其它線程亦是如此。
延時(shí)后的主要線程,獲得鎖,將條件置為真,并能過條件變量喚醒所有等待在條件變量上的10 個(gè)線程。
此時(shí)10 個(gè)線程再次爭(zhēng)相去獲取鎖,然后判斷條件為真,然后打印,釋放鎖給其它線程。

代碼演示:

#include <iostream> #include <thread> #include <chrono> #include <mutex> #include <condition_variable>using namespace std;condition_variable cv;mutex mtx;bool ready = false;void printId(int id) {unique_lock<mutex> ql(mtx);while (!ready){cv.wait(ql);}cout << "thread id:" << this_thread::get_id()<< " id = " << id << endl; }void go() {unique_lock<mutex> ql(mtx); //主線程中也要上鎖的。ready = true; //條件為真 才喚醒其他10個(gè)線程打印IDcv.notify_all(); }int main() {thread th[10];for (int i = 0; i < 10; i++){th[i] = thread(printId, i);}this_thread::sleep_for(chrono::seconds(5));go();for (auto& t : th){ t.join();}return 0; }

運(yùn)行結(jié)果:

總結(jié)

以上是生活随笔為你收集整理的C++11条件变量的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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