C++11多線程編程(五)——生產消費者模型之條件變量

當某個線程持有這把鎖的時候(就是所謂的加鎖),那麼這個線程是獨佔全部的資源,這裏的資源指的是執行的權限,其餘要搶奪資源的線程都不得不等待。在不少狀況下,這都容易適用,可是有些狀況下,卻會產生一些異常狀況。ios

在生產消費者模型當中,確定都會用到互斥鎖的機制的,當生產者往隊列中放數據的瞬間,消費者是不能取數據的,那這時候可能會遇見一個問題,若是生成者由於某些緣由,放數據過慢,可是消費者取數據很快,當隊列中沒有數據了,消費者還去取的話,就會發生異常狀況。有些人可能會說,加個條件判斷一下隊列是否爲空不就能夠了。編程

這個確定是固然能夠的,可是在隊列依舊沒有數據的這一段時間,是要不斷的循環判斷這個條件,CPU確定是會飆升的,浪費了不少沒必要要的資源。多線程

這時候咱們設想,可否設計這樣的一種機制,若是在隊列沒有數據的時候,消費者線程能一直阻塞在那裏,等待着別人給它喚醒,在生產者往隊列中放入數據的時候通知一下這個等待線程,喚醒它,告訴它能夠來取數據了。框架

因而多線程中的條件變量就橫空出世!函數

條件變量是多線程數據同步的一種操做,無論是用哪一種框架,哪一種語言實現多線程的功能,條件變量都是不得不考慮的一種狀況。C++中提供了#include <condition_variable>頭文件,裏面就包含了條件變量的相關類。其中有兩個很是重要的接口,wait()和notify_one(),wait()可讓線程陷入休眠狀態,意思就是不幹活了,notify_one()就是喚醒真正休眠狀態的線程,開始幹活了。固然還有notify_all()這個接口,顧名思義,就是通知全部正在等待的線程,起來幹活了。優化

如下是代碼的實現部分this

#include <iostream>
#include <deque>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
 
deque<int> q;
mutex mt;
condition_variable cond;
 
void thread_producer()
{
    int count = 10;
    while (count > 0)
    {
        unique_lock<mutex> unique(mt);
        q.push_front(count);
        unique.unlock();
        cout << "producer a value: " << count << endl;
        cond.notify_one();
        this_thread::sleep_for(chrono::seconds(1));
        count--;
    }
}
 
void thread_consumer()
{
    int data = 0;
    while (data != 1)
    {
        unique_lock<mutex> unique(mt);
        while (q.empty())
            cond.wait(unique);
        data = q.back();
        q.pop_back();
        cout << "consumer a value: " << data << endl;
        unique.unlock();
    }
}
 
int main()
{
    thread t1(thread_consumer);
    thread t2(thread_producer);
    t1.join();
    t2.join();
    return 0;
}

 

生產者:首先生產者利用unique_lock來加鎖,而後將生產的數據放入隊列,打印,解鎖,一旦解鎖以後,消費者得到了執行機會。spa

消費者:另外一方面消費者就會經過unique_lock得到控制權,也就是得到鎖,而後判斷隊列爲空的話就一直盜用wait()函數阻塞在那裏,等待其餘線程來喚醒它。而阻塞該線程時,該函數會自動解鎖,容許其餘線程執行。線程

生產者:再次回到生產者這裏,生產者線程利用利用條件變量cond.notify_one()來通知阻塞的線程起來幹活了。設計

消費者:阻塞在那裏的消費者線程一旦獲得notify喚醒,該函數取消阻塞並獲取鎖,而後取出隊列中的數據,並打印,最後解鎖。

生產者:再次回到生產者,而後生產者休眠1秒,這裏休眠是爲了模擬生產者生產慢的狀況,實際開發的時候不要去休眠。最後減一,進入下一次生產。

以上就是利用條件變量來實現生產消費者模型,這個會大大下降CPU的佔有率,固然代價就是編程稍微有點麻煩,但與這優化程序來比,這確定是值的。

更多精彩內容,請關注同名公衆:一點筆記alittle

相關文章
相關標籤/搜索