C 併發與多執行緒程式設計之互斥量 死鎖及解決辦法

2021-09-24 03:57:37 字數 1457 閱讀 1253

1 互斥量(mutex)

互斤量是個類物件,理解成一把鎖,多個執行緒嘗試用lock()成員來加鎖這把鎖頭,只有乙個執行緒能鎖定成功(成的標誌是lock()函式返回),加果沒鎖成功,那麼流程卡在lcok()這裡不斷的嘗試去鎖這把鎖頭。互斥量使用要小心,保護封據不多也不少,少了,沒達到保護效果,多了,影響效率。

2 互斥量的用法

2.1 lock()、unlock()

步驟:先lock(),操作共享資料, unlock();lock ()和unlock()更成對使用,有lock()必然要有unlock(),每呼叫一次lock(),必然應該呼叫一次unlock();不應該也不充許呼叫以lock()即呼叫了2次unlockk(),也不允許呼叫2個1ock()調1次用unlock(),這些非對稱數量的呼叫都會導致**不穩定。

為了防止大家忘記unlock(),引入了乙個叫std::lock.guard的類模板;你忘記unlock()不要緊,我替你unlock();類似智慧型指標(unique->ptr)。

2.2 std::lock_guard類模板

std:: lock_guard類模板:直接取代lock ()和unlock ()):也就是說,你用了lock-guard之後,再不能快用lock()和unlock()。相當於在lock_guard析構函式中進行了unlock()操作。

3 死鎖

比如我有兩把鎖(死鎖這個問題是由至少兩個鎖頭也就是兩個互斥量才能產生),金鎖(jinlock),銀鎖(yinlock),兩個執行緒a,b。

(1) 執行緒a執行的時候,這個執行緒先鎖金鎖,把金鎖lock()成功了,然後它去lock銀鎖,此時,出現了上下文切換

(2) 執行緒時執行了,這個執行緒先鎖銀鎖,因為銀鎖還沒有被鎖,所以銀鎖會lock ()成功,執行緒b去lock金鎖。此時此刻,死鎖就產生了,

(3) 執行緒a因為拿不到銀鎖頭,流程走不下去(所有後邊**有解鎖金鎖頭的但是流程走不下去,所以金鎖頭解不開)

(4) 執行緒b因為拿不到金鎖頭,流程走不下去(所有後邊**有解鎖銀鎖頭的但是流程走不下去,所以銀鎖頭解不開)

3.1 死鎖的一般解決方案

(1)只要保證這兩個互廳量上鎖的順序一致就不會死鎖。

(2)std: :lock()函式模板:一次鎖住兩個或者兩個以上的互斥量(至少兩個,多了不限,1個不行),它不存在這種因為再多個執行緒中因力鎖的順序問題導致死鎖的風險問題;

(3)std:: lock ()):如果互斥量中有乙個沒鎖住,它就在那裡等著,等所有互斥量都鎖住,它才能往下走(返回) , 要麼兩個互斥量都鎖住,要麼兩不互斥量都沒鎖住。如果只鎖了乙個,另外乙個沒鎖成功,則它立即把已經鎖住的解鎖。

(4)使用std:: lock()必須使用unlock().

3.2 std::lock_guard類模板的std::adopt_lock引數

std::adopt_lock是個結構體物件,起乙個標記作用:作用就是表示這個互斥量已經lock(),不需更在atd:lock_guard建構函式裡再對mutex進行lock().

C 多執行緒 互斥量 死鎖

在多執行緒的使用中,如果我們建立了多個執行緒,多個執行緒之間的執行順序是由cpu來完成排程的,因此我們如果需要在多執行緒中進行資料共享和通訊,就需要注意資料安全的問題,有可能我在乙個執行緒中正在執行對資料的操作,此時cpu通過上下文切換,把當前執行緒切換掉了,開始執行了別的執行緒,而別的執行緒本來希...

多執行緒之Mutex 互斥量

include include include long g count 0 long g sum 0 static const int g s count 10 critical section g csthreadparamer critical section g csthreadcode h...

多執行緒程式設計 互斥量

pthreads 使用 pthread mutex t 型別的變數來表示互斥量,同時在使用互斥量進行同步前需要先對它進行初始化,可以用靜態或動態的方式對互斥量進行初始化。對於靜態分配的 pthread mutex t 變數來說,只要將 pthread mutex initializer賦給變數就行了...