標籤:style 使用 ar line amp size ad 對象
pthread_cond_wait在把線程放進阻塞隊列後,自動對mutex進行解鎖(它內部有自己維護一個隊列),使得其他線程可以獲得加鎖的權利。這樣其它線程才能對臨界資源進行訪問並在適當的時候喚醒這個阻塞的進程。當pthread_cond_wait返回的時候又會自動給mutex加鎖,所以最後需要一個pthread_mutex_unlock()函數來解鎖。
假設另一個線程(線程2)鎖定了mutex並對已連結清單添加了一項。在對互斥對象解鎖後,線程2會立即調用函數pthread_cond_broadcast(&cond)或者pthread_cond_signal(&cond)。此操作之後,線程2將使所有等待cond條件變數的線程立即熟悉。這意味著第一個線程(仍處於pthread_cond_wait()調用中)現在將蘇醒。
然後pthread_cond_wait執行最後一個操作:重新鎖定mutex,一旦它鎖定了互斥對象,那麼pthread_cond_wait將返回並允許線程1繼續執行。此時,它可以馬上檢查列
表,查看它所感興趣的更改。
看例子:
pthread_mutex_lock(&mut);
while (x <= y) {
pthread_cond_wait(&cond, &mut);
}
/* operate on x and y */
pthread_mutex_unlock(&mut);
pthread_mutex_lock(&mut);
/* modify x and y */
if (x > y) pthread_cond_singal(&cond);
pthread_mutex_unlock(&mut);
這個例子的意思是,兩個線程要修改X和 Y的值,第一個線程當X<=Y時就掛起,直到X>Y時才繼續執行(由第二個線程可能會修改X,Y的值,當X>Y時喚醒第一個線程),即首先初始化一個普通互斥量mut和一個條件變數cond。
其實函數的執行過程非常簡單,在第一個線程執行到pthread_cond_wait(&cond,&mut)時,此時如果X<=Y,則此函數就將mut互斥量解鎖,再將第一個線程掛起 (不佔用任何CPU周期)。
而在第二個線程中,本來因為mut被第一個線程鎖住而阻塞,此時因為mut已經釋放,所以可以獲得鎖mut,並且進行修改X和Y的值,在修改之後,一個IF語句判定是不是X>Y,如果是,則此時pthread_cond_signal()函數會喚醒第一個線程,並在下一句中釋放互斥量mut。然後第一個線程開始從pthread_cond_wait()執行,首先要再次鎖mut , 如果鎖成功,再進行條件的判斷 (至於為什麼用WHILE,即在被喚醒之後還要再判斷,後面有原因分析),如果滿足條件,則被喚醒進行處理,最後釋放互斥量mut 。
至於為什麼在被喚醒之後還要再次進行條件判斷(即為什麼要使用while迴圈來判斷條件),是因為可能有“驚群效應”。有人覺得此處既然是被喚醒的,肯定是滿足條件了,其實不然。如果是多個線程都在等待這個條件,而同時只能有一個線程進行處理,此時就必須要再次條件判斷,以使只有一個線程進入臨界區處理