一。互斥量和條件變數簡介
互斥量(mutex)從本質上說是一把鎖,在訪問共享資源前對互斥量進行加鎖,在訪問完成後釋放互斥量上的鎖。對互斥量進行加鎖以後,任何其他試圖再次對互斥鎖加鎖的執行緒將會阻塞直到當前執行緒釋放該互斥鎖。如果釋放互斥鎖時有多個執行緒阻塞,所有在該互斥鎖上的阻塞執行緒都會變成可執行狀態,第乙個變為執行狀態的執行緒可以對互斥鎖加鎖,其他執行緒將會看到互斥鎖依然被鎖住,只能回去再次等待它重新變為可用。
條件變數(cond)是在多執行緒程式中用來實現"等待--》喚醒"邏輯常用的方法。條件變數利用執行緒間共享的全域性變數進行同步的一種機制,主要包括兩個動作:乙個執行緒等待"條件變數的條件成立"而掛起;另乙個執行緒使「條件成立」。為了防止競爭,條件變數的使用總是和乙個互斥鎖結合在一起。執行緒在改變條件狀態前必須首先鎖住互斥量,函式pthread_cond_wait把自己放到等待條件的執行緒列表上,然後對互斥鎖解鎖(這兩個操作是原子操作)。在函式返回時,互斥量再次被鎖住。
二。為什麼存在條件變數
首先,舉個例子:在應用程式中有連個執行緒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中,當icount < 100時,會呼叫pthread_cond_wait。而pthread_cond_wait在上面應經講到它會釋放mutex,然後等待條件變為真返回。當返回時會再次鎖住mutex。因為pthread_cond_wait會等待,從而不用一直的輪詢,減少cpu的浪費。在thread1和thread2中的函式pthread_cond_signal會喚醒等待cond的執行緒(即thread4),這樣當icount一到大於等於100就會去喚醒thread4。從而不致出現icount很大了,thread4才去處理。
需要注意的一點是在thread4中使用的while (icount < 100),而不是if (icount < 100)。這是因為在pthread_cond_singal()和pthread_cond_wait()返回之間有時間差,假如在時間差內,thread3又將icount減到了100以下了,那麼thread4就需要在等待條件為真了。
執行緒同步 互斥鎖 條件變數
在 執行緒同步 互斥鎖 一文中,我們分析了只用互斥鎖同步執行緒的弊端 cpu的效率和時效性不可兼得。下面,我們通過使用條件變數,在保證cpu效率的前提下,提高程式的時效性。只用互斥鎖同步執行緒,其cpu佔用率之所以高,是因為執行緒需要輪詢,即需要不停的檢查條件是否滿足。我們使用條件變數,當條件不滿足...
執行緒同步與互斥 條件變數
先上 include include include includepthread mutex t count lock pthread cond t count nonzero unsigned int count 0 pthread cond wait會把執行緒阻塞在這裡,同時釋放鎖 條件變數被...
Linux執行緒同步 細說 互斥鎖 條件變數
假設有多個執行緒共享的資源sum,與之相關聯的mutex 是lock s.假設每個執行緒對sum的操作很簡單,與sum的狀態無關,比如只是sum 那麼只用mutex足夠了.程式設計師只要確保每個執行緒操作前,取得lock,然後sum 再unlock即可.每個執行緒的對sum的操作 將像這樣 add ...