【并發(fā)編程十】c++線程同步——條件變量(condition-創(chuàng)新互聯(lián)

【并發(fā)編程十】c++線程同步——條件變量(condition_variable)
  • 一、互斥
  • 二、條件變量
    • 1、為何要引入條件變量?
    • 2、不使用條件變量
    • 3、使用條件變量
      • 3.1、互斥鎖有什么問題?
      • 3.2、條件變量
      • 3.3、條件變量成員函數(shù)
      • 3.4、demo
      • 3.4、總結(jié)
  • 三、future
  • 四、信號(hào)量

簡(jiǎn)介:
本篇文章,我們?cè)敿?xì)的介紹下c++標(biāo)準(zhǔn)庫提供的線程同步方法——條件變量(condition_variable)。

永春網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),永春網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為永春成百上千提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站制作要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的永春做網(wǎng)站的公司定做!一、互斥

參見【并發(fā)編程九】c++線程同步——互斥(mutex)

二、條件變量 1、為何要引入條件變量?
  • 例子
    在一條生產(chǎn)線上有一個(gè)倉庫,當(dāng)生產(chǎn)者生產(chǎn)時(shí)需要鎖住倉庫獨(dú)占,而消費(fèi)者去產(chǎn)品時(shí)也需要鎖住倉庫獨(dú)占。
    如果,生產(chǎn)者發(fā)現(xiàn)倉庫滿了,那么他就不能生產(chǎn)了,編程了阻塞狀態(tài)。但是此時(shí)生產(chǎn)者獨(dú)占倉庫,消費(fèi)者又無法進(jìn)入倉庫消耗產(chǎn)品,這樣就造成了一個(gè)僵死的狀態(tài)。

我們需要一種機(jī)制,當(dāng)互斥量被鎖住以后發(fā)現(xiàn)當(dāng)前線程還是無法完成自己的操作,那么它應(yīng)該釋放互斥量,讓其他線程哦工作。

  • 1、可以采用輪詢的方式,不停的查詢你需要的條件。
  • 2、讓系統(tǒng)來幫你查詢條件,使用條件變量。
2、不使用條件變量
  • demo
#include#include#include#include#includeusing namespace std;

mutex mtx;
dequeq;

//線程A,producer
void task1()
{int i = 0;
    while(true)
    {unique_locklock(mtx);
        if (q.size()< 1000)
        {if (i< 999)
            {q.push_back(i);
                i++;
            }
            else
            {i = 0;
            }
        }
        else
        {// std::this_thread::sleep_for(std::chrono::seconds(1));;
        }
    }
}

//線程B,consumer
void task2()
{int da = 0;
    while (true)
    {unique_locklock(mtx);
        if (!q.empty())
        {da = q.front();
            q.pop_front();
            cout<< "get value from que:"<< da<< endl;
            cout<< "que.size:"<< q.size()<cout<< "que.size:"<< q.size()<< endl;
    thread t2(task2);
    thread t1(task1);
 
    t1.join();
    t2.join();
}
  • 輸出

在這里插入圖片描述

3、使用條件變量 3.1、互斥鎖有什么問題?
  • 嘗試獲取鎖的人會(huì)一直等待,浪費(fèi)cpu資源。(功耗和性能浪費(fèi))
3.2、條件變量
  • 提供睡眠/喚醒機(jī)制,避免無意義的等待。

條件變量是允許多個(gè)線程相互交流的同步原語。它允許一定量的線程等待(可以定時(shí))另一線程的提醒,然后再繼續(xù)。條件變量始終關(guān)聯(lián)到一個(gè)互斥。
定義于頭文件

3.3、條件變量成員函數(shù)
  • 通知
通知成員函數(shù)解釋
notify_one通知一個(gè)等待的線程(公開成員函數(shù))
notify_all通知所有等待的線程(公開成員函數(shù))
  • 等待
等待成員函數(shù)解釋
wait阻塞當(dāng)前線程,直到條件變量被喚醒(公開成員函數(shù))
wait_for阻塞當(dāng)前線程,直到條件變量被喚醒,或到指定時(shí)限時(shí)長(zhǎng)后(公開成員函數(shù))
wait_until阻塞當(dāng)前線程,直到條件變量被喚醒,或直到抵達(dá)指定時(shí)間點(diǎn)(公開成員函數(shù))

簡(jiǎn)單說下,如果是新人,簡(jiǎn)單理解wait和notify_one兩個(gè)函數(shù)就行了,基本就明白了條件變量的原理,如下面的demo,wait就是等待notify的通知后再執(zhí)行

3.4、demo
#include#include#include#include#include#includeusing namespace std;

mutex mtx;
dequeq;
condition_variable cv;

//線程A,producer
void task1()
{int i = 0;
    while(true)
    {unique_locklock(mtx);
        if (q.size()< 1000)
        {if (i< 99)
            {q.push_back(i);
                cv.notify_one();//cv.notify_all();
                i++;
            }
            else
            {i = 0;
            }
        }
        else
        {cv.notify_one();
            //std::this_thread::sleep_for(std::chrono::seconds(1));;
        }
    }
}

//線程B,consumer
void task2()
{int da = 0;
    while (true)
    {unique_locklock(mtx);
        if (q.empty())//如果有多個(gè)消費(fèi)者,此處應(yīng)該為while(q.empty())
        {cv.wait(lock);
        }
        da = q.front();
        q.pop_front();
        cout<< "get value from que:"<< da<< endl;
        cout<< "que.size:"<< q.size()<< endl;
    }
}

int main()
{cout<< "que.size:"<< q.size()<< endl;
    thread t2(task2);
    thread t1(task1);
 
    t1.join();
    t2.join();
}

  • 輸出

在這里插入圖片描述

  • cpu占用率

在這里插入圖片描述

3.4、總結(jié)
  • 使用條件變量的意義在于,消費(fèi)者在沒有可消費(fèi)的產(chǎn)品時(shí),采用休眠,而非無意義的空轉(zhuǎn),浪費(fèi)cpu的計(jì)算資源。

參考:
1、https://www.apiref.com/cpp-zh/cpp/thread.html
2、https://en.cppreference.com/w/cpp/thread
3、書籍《c++服務(wù)器開發(fā)精髓》——張遠(yuǎn)龍

三、future
  • 【并發(fā)編程十一】c++線程同步——future
四、信號(hào)量
  • 參見【并發(fā)編程十二】c++線程同步——信號(hào)量(semaphore)

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)站標(biāo)題:【并發(fā)編程十】c++線程同步——條件變量(condition-創(chuàng)新互聯(lián)
分享路徑:http://muchs.cn/article22/dsspjc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗(yàn)定制開發(fā)、定制網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)、建站公司Google

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營(yíng)