有互斥變數,為何還有有條件變數

2021-07-22 18:04:57 字數 1683 閱讀 7470

一。互斥量和條件變數簡介

互斥量(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就需要在等待條件為真了。

**:

互斥量,條件變數

在程序喚醒與睡眠一文中,針對多程序的生產者 消費者問題,我們提出了基於訊號量的解決方案 該方案避免了程序在等待其要求的下一步執行條件時進入忙等待狀態 我們使用了三個訊號量,訊號量mutex用於保證生產者程序與消費者程序不會同時訪問緩衝區 訊號量empty用於保證當緩衝區滿是生產者被阻塞進入休眠狀態,...

linux c 執行緒池 互斥變數 條件變數

執行緒池主要實現模組multithreadtest.c include include include include include include typedef struct threadworker typedef struct threadpool static struct thread...

互斥鎖與條件變數

最近複習湯小丹的 計算機作業系統 西安電子科技大學出版社,第三版 程序 執行緒同步章節時,發現乙個疑問。在講程序同步時,提到了兩類方法 訊號量機制和管程機制。訊號量機制又包括四種 整型訊號量 記錄型訊號量 and型訊號量 訊號量集。如果採用整型訊號量或記錄型訊號量,則在共享多個資源時,可能出現程序死...