C++併發編程器第4章--同步併發操作

0. 引言

在這一章,主要介紹條件變量,期望(future),屏障等,並且也會給出相應的使用方式。

1. 等待某個事件或者條件

      首先考慮這樣一個場景,你正在坐火車去找你對象,爲了不錯過,你會怎麼辦呢?一般我們會要麼一夜不睡覺,自己檢查每一站看看是不是到達了對象的城市的火車站,或者我們會定個鬧鐘,當快到站的時候叫醒我們,但是鬧鐘可能會出錯,所以你也可能錯過站,當然如果你有一個小夥伴,在到站的時候能叫醒你,這樣你就可以安心休息了,但是你小夥伴就累了。好了,那麼這個場景如何應用到多線程呢?

     如果一個線程需要等待另一個線程完成某個任務才能執行,此時如何在兩個線程間進行操作的同步呢?

     參考我們上述坐火車找對象的場景,等待線程計作A,其他線程計作B,其同步操作的解決方案有設置flag,設置鬧鐘,以及條件變量。

     設置flag:

      在線程A中檢查flag是否被設置(該flag由mutex)表示,flag會由線程B設置。 該方案有兩個缺點:第一,當A在重複檢測flag時相當於polling,浪費CPU時間;第二,當在檢測flag時,mutex會被上鎖,這樣B無法獲得該鎖,阻礙了B設置flag的時間。

    設置鬧鐘:

    利用std::this_thread::sleep_for()函數設置一個鬧鐘,讓線程A休眠,當鬧鐘時間到了後在檢查flag,看看是否到達目的地,下面看一個例子

#include <mutex>
#include <thread>
#include <chrono>

bool flag;
std::mutex mut;
using chrono = std::chrono;

void wait_for_flag() {
    std::unique_lock<std::lock> lt(mut);
    while (!flag) {
        lt.unlock();
        std::this_thread::sleep_for(chrono::milliseconds(100));
        lt.lock();
    }
}

設置鬧鐘這種解決辦法,相對於設置flag方案有一定的提升,因爲sleep線程A,可以提升CPU的利用率,但該方案的缺點是設置的鬧鐘長度並非是完全理想的。

    條件變量:

    C++標準庫中提供了std::condition_variable 去更優的通知某個線程其等待的事件完成

1.1 等待條件變量

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章