欧美日韩在线第一页-欧美日韩在线观看精品-欧美日韩在线观看一区二区-欧美日韩在线免费看-欧美日韩在线视频不卡一区二区三区

編程代碼
新聞詳情

C++11多線(xiàn)程編程(五)——生產(chǎn)消費(fèi)者模型之條件變量

發(fā)布時(shí)間:2021-01-06 16:29:00 瀏覽次數(shù):2265

當(dāng)某個(gè)線(xiàn)程持有這把鎖的時(shí)候(就是所謂的加鎖),那么這個(gè)線(xiàn)程是獨(dú)占所有的資源,這里的資源指的是執(zhí)行的權(quán)限,其他要搶奪資源的線(xiàn)程都不得不等待。在很多情況下,這都容易適用,但是有些情況下,卻會(huì)產(chǎn)生一些異常情況。

在生產(chǎn)消費(fèi)者模型當(dāng)中,肯定都會(huì)用到互斥鎖的機(jī)制的,當(dāng)生產(chǎn)者往隊(duì)列中放數(shù)據(jù)的瞬間,消費(fèi)者是不能取數(shù)據(jù)的,那這時(shí)候可能會(huì)碰見(jiàn)一個(gè)問(wèn)題,如果生成者因?yàn)槟承┰颍艛?shù)據(jù)過(guò)慢,但是消費(fèi)者取數(shù)據(jù)很快,當(dāng)隊(duì)列中沒(méi)有數(shù)據(jù)了,消費(fèi)者還去取的話(huà),就會(huì)發(fā)生異常情況。有些人可能會(huì)說(shuō),加個(gè)條件判斷一下隊(duì)列是否為空不就可以了。


這個(gè)肯定是當(dāng)然可以的,但是在隊(duì)列依舊沒(méi)有數(shù)據(jù)的這一段時(shí)間,是要不斷的循環(huán)判斷這個(gè)條件,CPU肯定是會(huì)飆升的,浪費(fèi)了很多不必要的資源。

這時(shí)候我們?cè)O(shè)想,能否設(shè)計(jì)這樣的一種機(jī)制,如果在隊(duì)列沒(méi)有數(shù)據(jù)的時(shí)候,消費(fèi)者線(xiàn)程能一直阻塞在那里,等待著別人給它喚醒,在生產(chǎn)者往隊(duì)列中放入數(shù)據(jù)的時(shí)候通知一下這個(gè)等待線(xiàn)程,喚醒它,告訴它可以來(lái)取數(shù)據(jù)了。

于是多線(xiàn)程中的條件變量就橫空出世!

條件變量是多線(xiàn)程數(shù)據(jù)同步的一種操作,不管是用哪種框架,哪種語(yǔ)言實(shí)現(xiàn)多線(xiàn)程的功能,條件變量都是不得不考慮的一種情況。C++中提供了#include <condition_variable>頭文件,里面就包含了條件變量的相關(guān)類(lèi)。其中有兩個(gè)非常重要的接口,wait()和notify_one(),wait()可以讓線(xiàn)程陷入休眠狀態(tài),意思就是不干活了,notify_one()就是喚醒真正休眠狀態(tài)的線(xiàn)程,開(kāi)始干活了。當(dāng)然還有notify_all()這個(gè)接口,顧名思義,就是通知所有正在等待的線(xiàn)程,起來(lái)干活了。

以下是代碼的實(shí)現(xiàn)部分

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

生產(chǎn)者:首先生產(chǎn)者利用unique_lock來(lái)加鎖,然后將生產(chǎn)的數(shù)據(jù)放入隊(duì)列,打印,解鎖,一旦解鎖之后,消費(fèi)者獲得了執(zhí)行機(jī)會(huì)。

消費(fèi)者:另一方面消費(fèi)者就會(huì)通過(guò)unique_lock獲得控制權(quán),也就是獲得鎖,然后判斷隊(duì)列為空的話(huà)就一直盜用wait()函數(shù)阻塞在那里,等待其他線(xiàn)程來(lái)喚醒它。而阻塞該線(xiàn)程時(shí),該函數(shù)會(huì)自動(dòng)解鎖,允許其他線(xiàn)程執(zhí)行。

生產(chǎn)者:再次回到生產(chǎn)者這里,生產(chǎn)者線(xiàn)程利用利用條件變量cond.notify_one()來(lái)通知阻塞的線(xiàn)程起來(lái)干活了。

消費(fèi)者:阻塞在那里的消費(fèi)者線(xiàn)程一旦得到notify喚醒,該函數(shù)取消阻塞并獲取鎖,然后取出隊(duì)列中的數(shù)據(jù),并打印,最后解鎖。

生產(chǎn)者:再次回到生產(chǎn)者,然后生產(chǎn)者休眠1秒,這里休眠是為了模擬生產(chǎn)者生產(chǎn)慢的情況,實(shí)際開(kāi)發(fā)的時(shí)候不要去休眠。最后減一,進(jìn)入下一次生產(chǎn)。

以上就是利用條件變量來(lái)實(shí)現(xiàn)生產(chǎn)消費(fèi)者模型,這個(gè)會(huì)大大降低CPU的占有率,當(dāng)然代價(jià)就是編程稍微有點(diǎn)麻煩,但與這優(yōu)化程序來(lái)比,這肯定是值的。

在線(xiàn)客服 雙翌客服
客服電話(huà)
  • 0755-23712116
  • 13310869691
主站蜘蛛池模板: 国产精品成人观看视频国产 | 欧美日韩高清不卡免费观看| 欧美国产人妖另类色视频| 免费亚洲黄色| 亚洲一区二区三区中文字幕5566| 日毛片| 91在线高清视频| 婷婷六月久久综合丁香可观看| 久久视频免费在线观看| 成人国内精品久久久久影| 黄片毛片免费在线观看| 国产午夜免费| 伊人二区| 日本成日本片人免费| 99久久久久国产| 色综合天天色综合| 国产亚洲综合精品一区二区三区| 精品视频在线观看| 国产系列在线播放| 你懂的最新网址| 日韩一级欧美一级毛片在| 97超在线| 欧美一区二区三区久久久| 国产成人高清在线| 国产精品偷伦视频免费观看了| 欧美视频免费一区二区三区| 亚洲品质自拍视频| 三级小视频在线观看| 亚洲嗯啊| 国产亚洲欧美在线| 真实国产乱子伦精品一区二区三区 | 国产麻豆媒一区一区二区三区| 免费播放特黄特色毛片| 中文字幕三区| 中文学幕专区| 久久久这里只有精品加勒比| 88福利视频| 国产一级在线现免费观看| 亚洲酒色1314狠狠做| xxxxx18日本hd| 欧美一区不卡二区不卡三区|