【并發(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
  • 四、信號量

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

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

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

二、條件變量 1、為何要引入條件變量?
  • 例子
    在一條生產(chǎn)線上有一個倉庫,當(dāng)生產(chǎn)者生產(chǎn)時需要鎖住倉庫獨占,而消費者去產(chǎn)品時也需要鎖住倉庫獨占。
    如果,生產(chǎn)者發(fā)現(xiàn)倉庫滿了,那么他就不能生產(chǎn)了,編程了阻塞狀態(tài)。但是此時生產(chǎn)者獨占倉庫,消費者又無法進(jìn)入倉庫消耗產(chǎn)品,這樣就造成了一個僵死的狀態(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、互斥鎖有什么問題?
  • 嘗試獲取鎖的人會一直等待,浪費cpu資源。(功耗和性能浪費)
3.2、條件變量
  • 提供睡眠/喚醒機(jī)制,避免無意義的等待。

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

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

簡單說下,如果是新人,簡單理解wait和notify_one兩個函數(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())//如果有多個消費者,此處應(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é)
  • 使用條件變量的意義在于,消費者在沒有可消費的產(chǎn)品時,采用休眠,而非無意義的空轉(zhuǎn),浪費cpu的計算資源。

參考:
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
四、信號量
  • 參見【并發(fā)編程十二】c++線程同步——信號量(semaphore)

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

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

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

廣告

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

網(wǎng)站托管運營