C 11多執行緒學習 條件變數

2021-08-20 04:28:52 字數 3444 閱讀 7997

c++11中的std::condition_variable

首先,舉個例子:在應用程式中有4個程序thread1,thread2,thread3和thread4,有乙個int型別的全域性變數icount。icount初始化為0,thread1和thread2的功能是對icount的加1,thread3的功能是對icount的值減1,而thread4的功能是當icount的值大於等於100時,列印提示資訊並重置icount=0。

互斥量**:

thread1/2:

while (1)

thread4:

while(1)

else

}

在上面**中由於thread4並不知道什麼時候icount會大於等於100,所以就會一直在迴圈判斷,但是每次判斷都要加鎖、解鎖(即使本次並沒有修改icount)。這就帶來了問題一:cpu浪費嚴重。所以在**中新增了sleep(),這樣讓每次判斷都休眠一定時間。但這又帶來的第二個問題:如果sleep()的時間比較長,導致thread4處理不夠及時,等icount到了很大的值時才重置。對於上面的兩個問題,可以使用條件變數來解決。

條件變數**:

thread1/2:

while(1)

}

thread4:

while (1)

printf("icount >= 100\r\n");

icount = 0;

pthread_mutex_unlock(&mutex);

}

thread4在條件false的情況下呼叫pthread_cond_wait,這個函式會首先釋放鎖,然後將該執行緒阻塞在這裡(執行緒掛起於wait佇列中),這就解決了互斥量**中thread4輪詢損耗問題

在其他執行緒處會通過pthread_cond_signal方法重新喚醒阻塞的所有執行緒,喚醒的執行緒在wait函式中競爭lock,成功獲取鎖的執行緒會return,其他執行緒繼續阻塞。

在thread4中使用的while (icount < 100),而不是if (icount < 100)。這是因為在pthread_cond_singal()和pthread_cond_wait()的lock之間有時間差,假如在時間差內,thread3又將icount減到了100以下了,那麼thread4在pthread_cond_wait()返回之後,顯然應該再檢查一遍icount的大小,這就是while的用意。

pthread_cond_signal放在lock,unlock之間和之後都可以:

1. 在之間的情況下,可能會把等待執行緒餓死,原因是signal訊號發出時未unlock,所有等待執行緒繼續阻塞在wait

2. 在之後的情況下,可能會在signal訊號發出後,有其他執行緒修改了條件變數,情況同上一節的第三點問題

c++11的條件變數類的定義:

class condition_variable   

~condition_variable() _noexcept

condition_variable(const condition_variable&) = delete;

condition_variable& operator=(const condition_variable&) = delete;

void notify_one() _noexcept

void notify_all() _noexcept

void wait(unique_lock& _lck)

template

void wait(unique_lock& _lck, _predicate _pred)

template

_cv_status wait_for(unique_lock& _lck, const chrono::duration<_rep, _period>& _rel_time)

template

bool wait_for(unique_lock& _lck, const chrono::duration<_rep, _period>& _rel_time, _predicate _pred)

template

_cv_status wait_until( unique_lock& _lck, const chrono::time_point<_clock, _duration>& _abs_time)

template

bool wait_until(unique_lock& _lck, const chrono::time_point<_clock, _duration>& _abs_time, _predicate _pred)

_cv_status wait_until( unique_lock& _lck, const xtime *_abs_time)

template

bool wait_until(unique_lock& _lck, const xtime *_abs_time, _predicate _pred)

native_handle_type native_handle()

void _register(unique_lock& _lck, int *_ready)

void _unregister(mutex& _mtx)

private:

_***_t _***;

};

該類禁止了拷貝和賦值,將linux中的pthread進行了封裝,具有以下幾個類似的方法:

condition_variable::notify_one():喚醒乙個處於等待狀態的執行緒;

condition_variable::notify_all():喚醒所有處於等待狀態的執行緒;

condition_variable::wait():將執行緒置於等待狀態,直到被notify_***()喚醒;

condition_variable::wait_for():將執行緒置於等待狀態,直到一段時間結束後自動醒來或被notify_***()喚醒;

condition_variable::wait_until():將執行緒置於等待狀態,直到指定的時間點到來自動喚醒或被notify_***()喚醒;

std::cout

#include // std::thread

#include // std::mutex, std::unique_lock

#include // std::condition_variable

std::mutex mtx; // 全域性互斥鎖.

std::condition_variable cv; // 全域性條件變數.

bool ready = false; // 全域性標誌位.

void do_print_id(int id)

void go()

int main()

C 11 多執行緒同步 互斥鎖 條件變數

在多執行緒程式中,執行緒同步 多個執行緒訪問乙個資源保證順序 是乙個非常重要的問題,linux下常見的執行緒同步的方法有下面幾種 這篇部落格只介紹互斥量和條件變數的使用。通常情況下,互斥鎖和條件變數是配合使用的,互斥鎖用於短期鎖定,主要保證執行緒對臨界區的進入 條件變數用於執行緒長期等待,在wait...

C11執行緒管理 條件變數

c11提供另外一種用於等待的同步機制,它可以阻塞乙個或者多個執行緒,直到收到另外乙個執行緒發出的通知或者超時,才會喚醒當前阻塞的執行緒。條件變數要和互斥量配合起來使用。condition variable,配合std unique lock進行wait操作。condition variable an...

C 11 多執行緒

新特性之描述 雖然 c 11 會在語言的定義上提供乙個記憶體模型以支援執行緒,但執行緒的使用主要將以 c 11 標準庫的方式呈現。c 11 標準庫會提供型別 thread std thread 若要執行乙個執行緒,可以建立乙個型別 thread 的實體,其初始引數為乙個函式物件,以及該函式物件所需要...