1. 程式人生 > >二值訊號量和互斥鎖到底有什麼區別?

二值訊號量和互斥鎖到底有什麼區別?

原文連結:https://www.cnblogs.com/codescrew/p/8970514.html

在說明之前我先丟擲結論:互斥鎖和二值訊號量在使用上非常相似,但是互斥鎖解決了優先順序翻轉的問題

假定我們現在有三個任務,task1,task2,task3,任務優先順序task1最高,然後依次降低。我們知道在系統排程的時候當兩個任務同時處於就緒態的時候,系統會優先執行優先順序高的任務

好了,讓我們來看兩個案例

優先順序翻轉分析(使用訊號量)

 在例子中,我們使用pend()函式來表示獲取訊號量,用post()函式來表示釋放訊號量

如上圖所示,過程分下面幾步

1.一開始task3開始執行,先獲取到訊號量

2.task1開始執行嘗試去獲取訊號量失敗被阻塞等待task3執行完

3.task3執行過程中,task2被觸發,由於其優先順序高於task3,task2被執行,浪費了大量時間

4.繼續執行task3,執行完後釋放訊號量

5.task1繼續執行

看到這裡我們可以得知,本應該優先順序最高的task1結果居然是最後開始執行的,這就是優先順序反轉現象。這明顯是不利的。比如如果有安裝看門狗,task1在長時間沒有得到執行,就會觸發看門狗,導致系統的重啟。

改進分析(使用互斥鎖)

  在例子中,我們使用lock()函式來表示獲取互斥鎖,用unlock()函式來表示釋放互斥鎖

如上圖所示,過程分下面幾步

1.一開始task3開始執行,先獲取到互斥鎖

2.task1開始執行嘗試去獲取互斥鎖失敗被阻塞等待task3執行完,但是此時提升task3的優先順序,讓其優先順序跟自己一樣

3.task3執行過程中,task2被觸發,由於其優先順序低於task3(第2步被提升過),task2等待執行

4.繼續執行task3,執行完後釋放互斥鎖

5.task1繼續執行

6.task1執行完,執行task2

所以過程跟前面的雖然一樣,但是互斥鎖多做了一個步驟就是將task3的優先順序提升到task1的級別,防止task2中途出來攪局浪費大量時間

生活中的例項類比

使用訊號量的情況:

領導在臺上講話。場內三個角色,領導,組長,小兵。

小兵先拿起話筒說話,領導要講話發現沒有話筒,就等待小兵講完。

組長要講話,由於他比較野蠻,不需要話筒,並制止了小兵說話,自己開始說。

組長講完,小兵接著講

小兵講完,把話筒給領導,領導講完

使用互斥鎖的情況:

領導在臺上講話。場內三個角色,領導,組長,小兵。

小兵先拿起話筒說話,領導要講話發現沒有話筒,就等待小兵講完,並且跟小兵說,現在你就是領導的身份

組長要講話,但是他發現領導已經賦予了小兵比自己更高的許可權,自己沒有權力打斷,只好作罷

小兵講完,把話筒給領導,領導講完

這時候組長才開始講話