讀者-寫著問題中寫者優先的實現
讀者一寫者問題是一個用訊號量實現的經典程式同步問題。在系統中,一個資料集( 如檔案或記錄) 被幾個併發程式共享,這些執行緒分兩類,一部分只要求進行復操作,稱之為“讀者”;另一類要求寫或修改操作,我們稱之為“寫者“。
一般而言,對一個資料集,為了保證資料的完整性、正確性,允許多個讀者程式同時訪問,但是不允許一個寫者程式同其它任何一個程式(讀者或者寫者)同時訪問,而這類問題就稱之為”讀者-寫者“問題。
讀者優先的演算法在作業系統相關的書籍中都有介紹,這是一種最簡單的解決辦法:當沒有寫程式正在訪問共享資料集時,讀程式可以進入訪問,否則必須等待。而讀者優先的演算法存在“餓死寫者”執行緒的問題:只要有讀者不斷到來,寫者就要持久地等待,直到 所有的讀者都讀完且沒有新的讀者到來時寫者才能寫資料集。而在很多情況下我們需要避免”餓死寫者“,故而採用寫者優先演算法:
在寫者優先演算法中,我們要實現的目標是:
1.要讓讀者與寫者之間、以及寫者與寫者之問要互斥地訪同資料集;
2.在無寫程式到來時各讀者可同時訪問資料集;
3.在讀者和寫者都等待時訪問時寫者優先.
一種演算法實現:
我們將用兩個不同的互斥訊號量分別實現讀者與寫者間的互斥及各寫者程式間的互斥:以互斥訊號量Wmutex實現各寫者問的互斥,互斥訊號量Rmutex實現各讀者與寫者問的互斥;
設定兩個整型變數Wcount和Rcount分別記錄等待的寫者數和正在讀的讀者數,因Wcount、Rcount都是共享變數,因此還要設定兩個互斥訊號量Mutl和Mut2以實現程式對這兩個變最的互斥訪問.
用訊號量機制實現的寫者優先的演算法如 :
- Var Mut1,Mut2,Wmutex,Fmutex:Semaphore;
- Rcount,Wcount:integer;
- Mut1:=Mut2:=WMutex:=Fmutex:=1;
- Rcount:=Wcount:=0;
- //Fmutex --> 讀者寫者互斥
- //WMutex --> 寫者互斥
- //Mut1 --> access to Rcount && 競爭Fmutex
- //Mut2 --> access to Wcount
- Writer:begin
- Wait(Mut1);
- Wcount:=Wcount+1;
- If Wcount=1 then Wait(Fmutex); //如有讀者,寫者阻塞在此處
- Signal(Mut1);
- Wait(WMutex);
- 寫操作;
- Signal(Wmutex);
- Wait(Mut1);
- Wcount:=Wcount-1;
- If Wcount=0 then Signal(Fmutex);
- Signal(Mut1);
- end
- Reader:begin
- Wait(Mut1); //讀者需要先申請Mut1,如果有寫者在等待Fmutex,則讀者被阻塞,寫者優先
- Signal(Mut1); //立即釋放Mut1,使寫者可以隨時申請到Mut1
- Wait(Mut2);
- Rcount:=Rcount+1;
- If Rcount=1 then Wait(Fmutex); //第一個讀者進入時,申請Fmutex;如有寫者,第一個讀者會阻塞在此處
- Signal(Mut2);
- 讀操作;
- Wait(Mut2);
- Rcount:=Rcount-1;
- If Rcount=0 then Signal(Fmutex); //最後一個讀者退出時,釋放Fmutex
- Singal(Mut2);
- end
程式碼解釋:
1:
讀者、寫者均按照Mut1、Fmutex的順序申請訊號量。
2:
寫者獲得Fmutex後,直至最後一個寫者釋放Fmutex,讀者均被阻塞。
讀者獲得Fmutex後,直至最後一個讀者(不包含由於Mut1被阻塞的讀者)釋放Fmutex,寫者均被阻塞。
3.
讀者申請到Mut1後立即釋放;
而寫者申請到Mut1後,就一直佔用不放,直至申請到Fmutex。
4.總結
Fmutex的作用就是寫者、讀者間的互斥;
Mut1的額外作用就是幫助寫者優先競爭到Fmutex。
程式碼的思路比較混亂,歡迎大家指正錯誤。
看到一篇文章,也是討論讀者寫者問題的,思路比我這篇清晰的多,文章地址如下:http://blog.csdn.net/cz_hyf/archive/2009/08/13/4443551.aspx
相關文章
- 作業系統實驗——讀者寫者模型(寫優先)作業系統模型
- socket 實現的 web 伺服器在 Windows 下的讀寫問題Web伺服器Windows
- Kubernetes 中實現 MySQL 的讀寫分離MySql
- 讀者寫者與生產者消費者應用場景
- 團隊4(先這麼寫著
- 團隊6(先這麼寫著
- 團隊7(先這麼寫著
- 線上MySQL讀寫分離,出現寫完讀不到問題如何解決MySql
- SpringBoot 專案優雅實現讀寫分離Spring Boot
- java實現生產者消費者問題Java
- JUC之讀寫鎖問題
- Shiro效能優化:解決Session頻繁讀寫問題優化Session
- (MariaDB/MySQL)MyISAM儲存引擎讀、寫操作的優先順序MySql儲存引擎
- ShardingSphere(七) 讀寫分離配置,實現分庫讀寫操作
- 【Mongo】Mongo讀寫分離的實現Go
- node的讀寫流簡易實現
- 關於利用go實現非同步讀寫的寫法分享Go非同步
- 生產者消費者問題-C++程式碼實現C++
- Python中檔案的讀寫、寫讀和追加寫讀三種模式的特點Python模式
- 冴羽答讀者問:怎麼才能像你一樣寫文章如喝水?
- ProxySQL實現MySQL讀寫分離MySql
- Python中的檔案讀寫-實際操作Python
- Mysql(MyISAM)的讀寫互斥鎖問題的解決方法MySql
- Java中的讀/寫鎖Java
- 基於Sharding-Jdbc 實現的讀寫分離實現JDBC
- 原生鴻蒙的成長史中,書寫著無數鴻蒙先鋒的故事鴻蒙
- 面試官:Zookeeper怎麼解決讀寫、雙寫併發不一致問題,以及共享鎖的實現原理?面試
- 7.7 實現程式記憶體讀寫記憶體
- “蟒蛇書”讀者群專屬——問題集錦,新入群讀者必看~
- 關於onethink 目錄,檔案讀寫檢測函式中的問題函式
- 冴羽答讀者問:除程式碼外,就沒別的優先順序很高的愛好了嗎?
- java編寫生產者/消費者模式的程式。Java模式
- 專題《一》mysql優化 ---------主從複製,讀寫MySql優化
- 寫給 Android 開發者的 Gradle 系列(三)撰寫 pluginAndroidGradlePlugin
- 寫給 Android 開發者的 Gradle 系列(二)撰寫 taskAndroidGradle
- 位元組面試:什麼是讀寫分離?讀寫分離的底層如何實現?面試
- 答讀者問:關於隱式 id 重複的問題
- Flink實戰之寫Hive效能問題Hive
- Python中的檔案讀寫Python