使用訊號量Semaphore實現沒有飢餓問題的鎖
參考LittleBookOfSemaphores中的Morris’s Solution
原理及程式碼實現
設定鎖屬性如下
我們設定有三個執行緒waiting空間:room1,room2,room3
其中room3是隱式設定的,裡面同一時間只能有一個執行緒,也可以說是互斥的
初始化鎖如下
我們的原理如下
- 先將一段時間內發出獲取鎖請求的執行緒都放入
room1
,也就是阻塞在圖中程式碼第48行 - 由於訊號量s1初始值為1,第一個進入
room1
的執行緒可以繼續執行48行之後的內容,它可以進入room2
,也就是被阻塞在圖中程式碼第67行的位置。
它在room2
中進行了一個操作,就是判斷自己之後是否還有執行緒在room1
中被阻塞,若有的話,隨機喚醒一個進入room2
,若沒有了,就通知room2
中的執行緒可以依次進入room3
。 - 當
room1
中的執行緒全部進入room2
,最後一個執行緒發出s2的post,room2
中的隨機一個執行緒被喚醒,在圖中程式碼第69行開始繼續執行,離開room2
(進入room3
),執行執行緒的主體程式,然後釋放鎖 - 在釋放鎖時,執行緒會回頭判斷身後
room2
中是否還有執行緒被阻塞,若有,隨機喚醒一個進入room3
,若沒有了,就通知這段時間內被阻塞在room1
門外也就是圖中程式碼第42行的執行緒可以依次進入room1
。
獲取鎖
釋放鎖
通過這一種方式,我們一批一批處理請求獲得鎖的執行緒,緩解了有執行緒從一開始就被阻塞,直到幾乎所有執行緒都執行完才輪到執行的飢餓問題。
效果驗證
為了證明確實較好地解決了飢餓問題,我設定一個陣列starve,用來儲存各個執行緒的飢餓值。
- 當有一個執行緒執行acquire鎖的時候,該執行緒的飢餓值+1,且所有執行緒的飢餓值乘2
- 當執行緒執行release鎖的時候,對應飢餓值清0。
- 當我們執行room3中的執行緒主體部分時,列印所有執行緒的當前飢餓情況,並累加到一個sum值中,執行全部執行緒結束後列印總飢餓度sum。同時我們也通過maxx變數記錄最大飢餓值。
執行結果:
總飢餓值為77208,最大飢餓度為1024
這樣看好像還看不出什麼,但是我設定了一個會產生飢餓的鎖進行比對
簡單的單訊號量存在飢餓問題的互斥鎖:
也是一樣的飢餓演算法
最大飢餓度就達到誇張的10173741824!!
兩者相比就能看出優化效果之好了
相關文章
- Semaphore-訊號量的實現分析
- 10. Semaphore ||(訊號量)
- Semaphore訊號量原始碼解析原始碼
- 原始碼分析:Semaphore之訊號量原始碼
- 無名訊號量實現哲學家問題
- Java訊號量實現程式同步問題:水果蘋果香蕉問題Java蘋果
- [java併發程式設計]基於訊號量semaphore實現限流器Java程式設計
- 利用訊號量semaphore實現兩個程式讀寫同步 Linux CLinux
- iOS GCD (四) dispatch_semaphore 訊號量iOSGC
- Java併發工具類(訊號量Semaphore)Java
- java-多執行緒-CountDownLatch(閉鎖) CyclicBarrier(柵欄) Semaphore(訊號量)-Java執行緒CountDownLatch
- 有名訊號量實現消費者生產者問題
- 飢餓的程式設計師程式設計師
- go中semaphore(訊號量)原始碼解讀Go原始碼
- java多執行緒中的死鎖、活鎖、飢餓、無鎖都是什麼鬼?Java執行緒
- Java併發程式設計實戰--計數訊號量(Semaphore)Java程式設計
- 互斥鎖和訊號量有什麼不同?(譯)
- 模擬epoll的飢餓場景
- 有名訊號量實現讀者-寫者問題(讀者優先)
- Python執行緒專題5:訊號量與有邊界的訊號量Python執行緒
- Linux中訊號量的實現Linux
- 高可用之限流-03-Semaphore 訊號量做限流
- 併發程式設計之臨界區\阻塞\非阻塞\死鎖\飢餓\活鎖程式設計
- Python中使用共享變數+訊號量實現程序間的實時通訊Python變數
- 關於oracle資料庫訊號量的問題Oracle資料庫
- Python-訊號量和執行緒池-semaphore ThreadPollPython執行緒thread
- system -v 訊號量的使用
- 透視國產手機供應鏈:從來沒有飢餓營銷 斷貨與庫存高發
- Jtti:linux下訊號量和互斥鎖有哪些區別?JttiLinux
- Java併發基礎-鎖的使用及原理(可重入鎖、讀寫鎖、內建鎖、訊號量等)Java
- 又是訊號量和共享記憶體沒有釋放的db待機記憶體
- Redis 實戰 —— 08. 實現自動補全、分散式鎖和計數訊號量Redis分散式
- Swoole 原始碼分析——鎖與訊號量模組原始碼
- 作業系統 訊號量vs互斥鎖作業系統
- Java多執行緒併發工具類-訊號量Semaphore物件講解Java執行緒物件
- 關於面試“有戲”和“沒戲”的訊號面試
- 無名訊號量實現相關程式同步
- 訊號量實現生產者消費者(程式碼邏輯有問題,不適合多個消費者,不常用)