C++條件變量

1、有什麼用:html

當須要死循環判斷某個條件成立與否時【true or false】,咱們每每須要開一個線程死循環來判斷,這樣很是消耗CPU。使用條件變量,可讓當前線程wait,釋放CPU,若是條件改變時,咱們再notify退出線程,再次進行判斷。this

2、其餘解釋spa

想要修改共享變量(即「條件」)的線程必須:
1. 得到一個std::mutex
2. 當持有鎖的時候,執行修改動做
3. 對std::condition_variable執行notify_one或notify_all(當作notify動做時,沒必要持有鎖)

即便共享變量是原子性的,它也必須在mutex的保護下被修改,這是爲了可以將改動正確發佈到正在等待的線程。

任意要等待std::condition_variable的線程必須:
1. 獲取std::unique_lock<std::mutex>,這個mutex正是用來保護共享變量(即「條件」)的
2. 執行wait, wait_for或者wait_until. 這些等待動做原子性地釋放mutex,並使得線程的執行暫停
3. 當得到條件變量的通知,或者超時,或者一個虛假的喚醒,那麼線程就會被喚醒,而且得到mutex. 而後線程應該檢查條件是否成立,若是是虛假喚醒,就繼續等待。線程

【注: 所謂虛假喚醒,就是由於某種未知的罕見的緣由,線程被從等待狀態喚醒了,但其實共享變量(即條件)並未變爲true。所以此時應繼續等待】code

 https://en.cppreference.com/w/cpp/thread/condition_variablehtm

3、代碼blog

std::deque<int> q; std::mutex mu; std::condition_variable cond; void function_1() //生產者 { int count = 10; while (count > 0) { std::unique_lock<std::mutex> locker(mu); q.push_front(count); locker.unlock(); cond.notify_one(); // Notify one waiting thread, if there is one. std::this_thread::sleep_for(std::chrono::seconds(1)); count--; } } void function_2() //消費者 { int data = 0; while (data != 1) { std::unique_lock<std::mutex> locker(mu); while (q.empty()) cond.wait(locker); // Unlock mu and wait to be notified data = q.back(); q.pop_back(); locker.unlock(); std::cout << "t2 got a value from t1: " << data << std::endl; } } int main() { std::thread t1(function_1); std::thread t2(function_2); t1.join(); t2.join(); return 0; }

 

核心:隊列

①、在消費者裏判斷隊列是否爲空後,若是不爲空則wait,等待生產者發送notify信號作用域

②、在生產者那裏,若是生產了任務,則發送notify信號,告訴消費者能夠試圖退出wait,判斷隊列是否爲空,若是有任務則調度處理任務,若是仍是空則說明這次notify是錯誤的,多是其餘地方發出來干擾的,生產者繼續wait。it

③、流程:

軟件開啓,生成消費者線程消費隊列,應該是一個while循環,在循環裏獲取鎖,再來一個while循環判斷條件,若是條件不成立則wait,wait會自動釋放鎖;

此時消費者已經沒有鎖了,在生產者線程裏,獲取鎖,而後往裏面加任務,退出做用域釋放鎖,而後notify告知消費者退出wait,消費者從新獲取鎖,而後從隊列裏取任務;

整個過程,生產者加任務時生產者持有鎖,消費者取任務時消費者持有鎖。

 

對於此處補充:https://www.cnblogs.com/judes/p/11132918.html

相關文章
相關標籤/搜索