(1)互斥量是保護臨界區的另一種方法,當執行執行緒在臨界區的執行時間很長時,那麼就最好使用互斥量了,否則會造成其他的執行緒將會在臨界區外忙等,浪費cpu時間;此時其他執行緒發現臨界區已經被互斥量鎖住,那麼它們將會阻塞;當互斥量被釋放時,有多個執行緒在阻塞,多個執行緒均會被喚醒,但是只有乙個執行緒可以獲得該鎖,其他的執行緒將會繼續阻塞;
(2)當執行執行緒需要在臨界區睡眠時,那麼就最好使用互斥量,如果採用自旋鎖,那麼其他的執行緒將會在臨界區外忙等,浪費cpu時間;
(3)posix的互斥量支援遞迴加鎖和非遞迴加鎖,對於非遞迴加鎖可能會造成死鎖,試想如果乙個已經持有某互斥量的執行緒繼續想要持有該鎖,由於不支援遞迴,因此程式將會死鎖(自己將自己鎖死),進而我們可能需要修改程式的邏輯;而遞迴加鎖,雖然可以讓該執行緒繼續執行,但是會使得臨界區的資料被破壞,造成程式也有可能會崩潰
互斥量的實現
(c++封裝linux的pthread系統呼叫)
class mutex final
int err = pthread_mutex_init(&_mutex, &attr);
(void) err;
} ~mutex()
int lock()
int unlock()
pthread_mutex_t* getmutexptr()
private:
pthread_mutex_t _mutex;
bool _processshared;
};
說明幾點:
(1)_processshared引數為是否支援跨程序的互斥量,預設為單程序的false;互斥量的屬性為pthread_mutex_normal,即不允許遞迴加鎖;
(2)pthread_mutex_t* getmutexptr()是為了條件變數而實現的,下文介紹;
(3)利用c++中建構函式和析構函式來初始化和銷毀乙個互斥量;
互斥量的使用
class mutexlockguard final
~mutexlockguard()
private:
mutex& _mutex;
};
說明:mutexlockguard中持有該_mutex;利用c++中建構函式和析構函式來申請和釋放乙個互斥量;
(1)當在臨界區中,需要等待某個條件成立時,我們應該使用條件變數,在如下**片段1中,如果_count 大於0時,我們需要等待該條件,即需要_cond.wait();該_cond.wait()過程是將會把呼叫執行緒放到等待條件的執行緒列表上,然後對該互斥量解鎖;此時在互斥量解鎖期間,又有新的執行緒進入該臨界區,條件尚未發生,_cond.wait()會繼續這一過程;
(2)在**片段2中,首先會進行條件檢查(已經被同乙個互斥量鎖主,睡眠的執行緒不可能錯過),如果_count==0 _cond.wakeall()將會喚醒執行緒,記住需要在條件變化後再喚醒執行緒;
(3)首先_cond.wait()需要在_mutex已經上鎖的情況下才能呼叫,因為_cond.wait()涉及到解鎖的過程;
(4)需要使用while (_count > 0),而不是 if (_count > 0),原因為當執行緒從_cond.wait()喚醒時,此時互斥量會繼續被鎖住(此時多個執行緒對互斥量爭用的問題),很有可能此時的條件會被其他執行緒修改,造成_count > 0的條件不成立,因此需要繼續判斷的;
(5)多次執行_cond.wakeall()傳送訊號時,如果沒有任何執行緒阻塞在該等待條件列表上,那麼這個訊號會丟失,但是不影響程式;
**片段1:
mutexlockguard lock(_mutex);
while (_count > 0) //impotant
**片段2:
if (_count == 0)
條件變數的實現:
class condition final
~condition()
int wait()
int waitforseconds(size_t seconds)
int wake()
int wakeall()
private:
mutex& _mutex;
pthread_cond_t _cond;
};
說明幾點:
(1)wake為喚醒至少乙個執行緒;而wakeall為喚醒所有的執行緒;waitforseconds(size_t seconds)為等待seconds秒後,條件還未出現,那麼執行緒將會重新獲得互斥量(此時多個執行緒對互斥量爭用的問題);
(2)wait()的實現需要使用_mutex.getmutexptr()中pthread_mutex_t型別的_mutex;
互斥量和條件變數
一。互斥量和條件變數簡介 互斥量 mutex 從本質上說是一把鎖,在訪問共享資源前對互斥量進行加鎖,在訪問完成後釋放互斥量上的鎖。對互斥量進行加鎖以後,任何其他試圖再次對互斥鎖加鎖的執行緒將會阻塞直到當前執行緒釋放該互斥鎖。如果釋放互斥鎖時有多個執行緒阻塞,所有在該互斥鎖上的阻塞執行緒都會變成可執行...
互斥量,條件變數
在程序喚醒與睡眠一文中,針對多程序的生產者 消費者問題,我們提出了基於訊號量的解決方案 該方案避免了程序在等待其要求的下一步執行條件時進入忙等待狀態 我們使用了三個訊號量,訊號量mutex用於保證生產者程序與消費者程序不會同時訪問緩衝區 訊號量empty用於保證當緩衝區滿是生產者被阻塞進入休眠狀態,...
互斥量(互斥鎖)與條件變數
使用pthread的互斥介面來保護資料,確保同一時間只有乙個執行緒訪問資料。互斥量從本質上來說是把鎖。條件變數是執行緒可用的另一種同步機制。條件變數給多個執行緒提供了乙個會和的場所。條件變數與互斥量一起使用時,允許執行緒以無競爭的方式等待特定的條件發生。條件本身是由互斥量保護的。我們使用pthrea...