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 的實體,其初始引數為乙個函式物件,以及該函式物件所需要...