關於pthread_cond_wait()使用的理解pthread_cond_wait()是linux多線程同步實現的一種方法,表示等待某一個線程共享變量滿足了某種情況時 線程才能繼續執行 pthread_cond_wait()之後的代碼,如下面的示例代碼段所示,thread_func()函數中的代碼 示例是一種比較常見的等待共享變量的方式,這裡主要關注 while(head == NULL)的使用
struct xxx* head; /** 全局線程共享變量*/ pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; /** 為條件變量搭配的互斥鎖*/ pthread_cond_t cond = PTHREAD_COND_INITIALIZER; /** 定義全局線程共享的條件變量*/ staticvoid* thread_func(void*arg) { /** 首先先獲得互斥鎖,表示同一時間只能有一個線程等待條件變量 * 如果沒有保持只有一個線程監聽條件變量的話,那有可能會引起線程的"驚群"現象 */ pthread_mutex_lock(&mtx); /** 下面理解為什麼需要先判斷 head == NULL 的值(假設這裡就是需要等待 head == NULL ) * 根據pthread相關文檔理解: 假設線程1執行到pthread_cond_wait()時,首先線程釋放mtx互斥鎖, * 之後再開始等待pthread_cond_signal()或者pthread_cond_broadcast()發送過來的"條件滿足信號" * 假如這時候某另外的一個線程2獲得了mtx鎖並改變head的值,使得head == NULL 並發送了信號且 * 完成之後釋放了mtx鎖, 這時候可能系統存在線程3正在等待獲得互斥鎖,那麼現在有兩種情況:1.線程3 * 獲得鎖,之後對head進行了一些操作,之後可能發送了信號,再釋放了互斥鎖;2.線程1獲得了互斥 * 鎖mtx,那麼這時候線程1繼續原來等待的邏輯,由於等待時釋放了鎖,現在需要重新獲得這種情況也獲得了, * 這時候程序執行while(head == NULL)的判斷,ok, 現在能明白為什麼這裡需要判斷 head == NULL ?了,因為在 * 上面情況1中線程3比線程1可能更早一步獲得鎖之後對head操作並使得head != NULL ,事實上大型的系統可能會有更多 * 的線程同時在競爭一個互斥鎖,對於共享變量值的改變可能會有更多的情況,也就是說線程1進入等待之後釋放鎖, * 直到收到喚醒信號, 在去重新獲得鎖的過程中,不一定能在收到信號後作為第一個獲得鎖的線程,也就是在獲得鎖時 * 其他線程可能獲得鎖並改變了head的值,比如上面例子盡管線程2在head == NULL 時發出了信號。 * 線程1判斷head == NULL是否滿足,如果不滿足條件,則重新釋放mtx鎖,並進入信號等待的過程,重復上面喚醒的邏輯 * 直到 head == NULL 時,程序執行之後的邏輯,最後釋放mtx互斥鎖 */ while(head != NULL) { pthread_cond_wait(&cond, &mtx); } /** head == NULL 時執行的邏輯*/ ... pthread_mutex_unlock(&mtx);//臨界區數據操作完畢,釋放互斥鎖 return0; }以上所說的信號,並不是只unix/linux 信號量或者系統信號的概念,僅僅代表一種線程喚醒的通信方式