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

編程代碼
新聞詳情

C++ 線程間同步

發(fā)布時(shí)間:2021-03-29 09:36:33 最后更新:2021-03-30 09:02:29 瀏覽次數(shù):4083

0 前言

  • 多線程在運(yùn)行過程中,各個(gè)線程都是隨著 OS 的調(diào)度算法,占用 CPU 時(shí)間片來執(zhí)行指令做事情,每個(gè)線程的運(yùn)行完全沒有順序可言。
  • 在某些應(yīng)用場景下,一個(gè)線程需要等待另外一個(gè)線程的運(yùn)行結(jié)果,才能繼續(xù)往下執(zhí)行,這就涉及到線程之間的同步通信機(jī)制。
  • 線程間同步通信最典型的例子就是生產(chǎn)者-消費(fèi)者模型,生產(chǎn)者線程生產(chǎn)出產(chǎn)品以后,會(huì)通知消費(fèi)者線程去消費(fèi)產(chǎn)品;當(dāng)消費(fèi)者線程去消費(fèi)產(chǎn)品時(shí),發(fā)現(xiàn)還沒有產(chǎn)品生產(chǎn)出來,它需要通知生產(chǎn)者線程趕快生產(chǎn)產(chǎn)品,等生產(chǎn)者線程生產(chǎn)出產(chǎn)品以后,消費(fèi)者線程才能繼續(xù)往下執(zhí)行。

1 消費(fèi)者“被動(dòng)等待”

#include 
#include 
#include 

static std::mutex mtx;
static std::deque<int> dq;
static int productNum = 5;

void Producer()
{
    using namespace std::literals::chrono_literals;
    for (int i = 1; i <= productNum; ++i) {
        mtx.lock();
        dq.push_front(i);
        std::cout << "Producer 生產(chǎn)產(chǎn)品為: " << i << std::endl;
        mtx.unlock();
        // std::this_thread::sleep_for(1s);
    }
}

void Consumer()
{
    while (true) {
        if (dq.empty()) {
            continue;
        }
        mtx.lock();
        int data = dq.back();
        dq.pop_back();
        std::cout << "Consumer 消費(fèi)產(chǎn)品為: " << data << std::endl;
        mtx.unlock();
    }
}

int main()
{
    std::thread t1(Producer);
    std::thread t2(Consumer);
    t2.join();
    t1.join();
    std::cin.get();
}

程序運(yùn)行結(jié)果如下:

C++ 線程間同步

如果讓生產(chǎn)者線程每生產(chǎn)一個(gè)產(chǎn)品后休息(sleep) 1s,結(jié)果如下:

C++ 線程間同步

解釋:該例子中,生產(chǎn)者和消費(fèi)者分別對(duì)應(yīng)兩個(gè)線程。隊(duì)列中存在物品時(shí),消費(fèi)者去消費(fèi),否則空循環(huán),一直等待。

缺點(diǎn):當(dāng)雙端隊(duì)列中沒有物品時(shí),消費(fèi)者只會(huì)原地死等,不會(huì)去催。

2 消費(fèi)者“主動(dòng)出擊”

#include 
#include 
#include 
#include 
#include 
  
std::mutex mtx;
std::condition_variable cv;
std::vector<int> vec;
int productNum = 5;

void Producer()
{
    for (int i = 1; i <= productNum; ++i) {
        std::unique_lock<std::mutex> lock(mtx);
        while (!vec.empty()) {
            cv.wait(lock); // vec 不為空時(shí)阻塞當(dāng)前線程
        }
        vec.push_back(i);
        std::cout << "Producer生產(chǎn)產(chǎn)品: " << i << std::endl;
        cv.notify_all(); // 釋放線程鎖
    }
}

void Consumer()
{
    while (true) {
        std::unique_lock<std::mutex> lock(mtx);
        while (vec.empty()) {
            cv.wait(lock); // vec 為空時(shí)等待線程鎖。其他線程鎖釋放時(shí),當(dāng)前線程繼續(xù)執(zhí)行
        }
        int data = vec.back();
        vec.pop_back();
        std::cout << "Consumer消費(fèi)產(chǎn)品: " << data << std::endl;
        cv.notify_all();
    }
}

int main()
{
    std::thread t1(Producer);
    std::thread t2(Consumer);
    t2.join();
    t1.join();
    std::cin.get();
}

程序運(yùn)行結(jié)果如下:

C++ 線程間同步

解釋:該例子中,生產(chǎn)者和消費(fèi)者分別對(duì)應(yīng)兩個(gè)線程。只要 vector 中存在物品時(shí),生產(chǎn)者線程就阻塞,通知消費(fèi)者線程去消費(fèi);vector 中不存在物品時(shí),消費(fèi)者線程阻塞,通知生產(chǎn)者去生產(chǎn)。

3 線程加入方式 join 和 detach

join:采用 join 方式,t1、t2 亂序執(zhí)行,且外層主線程會(huì)等到 t1、t2 都結(jié)束了再繼續(xù)執(zhí)行后面的代碼。

detach:如果采用 detach 方式,t1、t2 亂序執(zhí)行,且脫離了外層主線程。外層主線程執(zhí)行結(jié)束時(shí),t1、t2 可能還沒結(jié)束,但此時(shí)程序就退出了。


如涉及侵權(quán),請(qǐng)相關(guān)權(quán)利人與我司聯(lián)系刪除

在線客服 雙翌客服
客服電話
  • 0755-23712116
  • 13310869691
主站蜘蛛池模板: 色婷婷综合网| 日韩a级毛片免费视频| 国产成人 免费观看| 91久久青青草原免费| 久久美女精品国产精品亚洲| 亚洲欧洲日产国码天堂| 久久一本精品久久精品66| 亚洲青青青网伊人精品| 免费欧美日韩| 欧美精品国产一区二区| 国产精品一区91| 黄色一级免费网站| 91资源视频| 国产精品视频全国免费观看| 免费看在线偷拍视频| 亚洲va中文字幕欧美不卡| 91在线公开视频| 一级国产20岁美女毛片| 日本一级特黄毛片免费视频| 亚洲视频在线精品| 伊人久久综合成人亚洲| 欧美成人精品一级高清片| 国产成人高清一区二区私人| 热综合一本伊人久久精品| 嗯~啊~哦~别~别停~啊黑人| 国产成人区| 国产精选自拍| 嘿嘿视频在线观看| 久久性生活片| 欧美成人免费午夜影视| 日本中文字幕乱码免费| 亚洲 欧美 中文 日韩专区| 亚洲视频91| 亚洲一区二区三区播放在线| 51精品视频在线观看视频| 一区二区三区国模大胆| 一级毛片在播放免费| 九九免费精品视频| 九九视频免费观看| 久久成人黄色| 三黄日本三级在线观看|