讀者寫者問題(讀者優先、寫者優先、公平競爭)
阿新 • • 發佈:2019-01-08
讀者優先:
1.寫者、讀者互斥訪問檔案資源。
2.多個讀者可以同時訪問檔案資源。
3.只允許一個寫者訪問檔案資源。
具體實現:
1.設定訊號量fileSrc實現讀寫者對臨界資源的訪問。
2.設定計數器readCount來統計訪問臨界資源的讀者數目,設定訊號量readCountSignal完成對readCount計數器資源的互斥訪問。
1.寫者執行緒的優先順序高於讀者執行緒。
2.當有寫者到來時應該阻塞讀者執行緒的佇列。
3.當有一個寫者正在寫時或在阻塞佇列時應當阻塞讀者程序的讀操作,直到所有寫者程序完成寫操作時放開讀者程序。
4.當沒有寫者程序時讀者程序應該能夠同時讀取檔案。
具體實現:
1.通過新增訊號量read實現寫者到來時能夠打斷讀者程序。
2.設定訊號量fileSrc實現讀寫者對臨界資源的訪問。
3.設定計數器writeCount來統計當前阻塞的寫者程序的數目,設定訊號量writeCountSignal完成對writeCount計數器資源的互斥訪問。
4.設定計數器readCount來統計訪問臨界資源的讀者數目,設定訊號量readCountSignal完成對readCount計數器資源的互斥訪問。
1.優先順序相同。
2.寫者、讀者互斥訪問。
3.只能有一個寫者訪問臨界區。
4.可以有多個讀者同時訪問臨界資源。
具體實現:
1.設定file訊號量實現對臨界資源的互斥訪問。
2.設定計數器readCount實現多個讀者訪問臨界資源,通過設定訊號量readCountSignal實現對readCount計數器的互斥訪問。
3.設定訊號量keySignal實現讀者和寫者的公平競爭(令牌)。
4.設定訊號量OneSignal實現只有讀者佇列或寫者阻塞在keySignal(對令牌資源的訪問控制)。
1.寫者、讀者互斥訪問檔案資源。
2.多個讀者可以同時訪問檔案資源。
3.只允許一個寫者訪問檔案資源。
具體實現:
1.設定訊號量fileSrc實現讀寫者對臨界資源的訪問。
2.設定計數器readCount來統計訪問臨界資源的讀者數目,設定訊號量readCountSignal完成對readCount計數器資源的互斥訪問。
寫者優先:/*初始化讀者佇列為0,檔案資源的初始值為1*/ int readCount = 0; semaphore readCountSignal = 1; reader() { while(true) { wait(readCountSignal); //申請讀者佇列計數器 if(!readCount) //如果讀者佇列為空,申請檔案資源 wait(fileSrc); readCount++; signal(readCountSignal); //釋放讀者計數器資源 ... perform read operation //執行臨界區程式碼 ... wait(readCountSignal); //申請讀者計數器資源 readCount--; if(!readCount) //如果讀者佇列為空,釋放檔案資源 signal(fileSrc); signal(readCountSignal); //釋放讀者計數器資源 } } writer() { while(true) { wait(file); //申請檔案資源 ... perform write operation //執行臨界區程式碼 ... signal(fileSrc); //釋放檔案資源 } }
1.寫者執行緒的優先順序高於讀者執行緒。
2.當有寫者到來時應該阻塞讀者執行緒的佇列。
3.當有一個寫者正在寫時或在阻塞佇列時應當阻塞讀者程序的讀操作,直到所有寫者程序完成寫操作時放開讀者程序。
4.當沒有寫者程序時讀者程序應該能夠同時讀取檔案。
具體實現:
1.通過新增訊號量read實現寫者到來時能夠打斷讀者程序。
2.設定訊號量fileSrc實現讀寫者對臨界資源的訪問。
3.設定計數器writeCount來統計當前阻塞的寫者程序的數目,設定訊號量writeCountSignal完成對writeCount計數器資源的互斥訪問。
4.設定計數器readCount來統計訪問臨界資源的讀者數目,設定訊號量readCountSignal完成對readCount計數器資源的互斥訪問。
公平競爭:/*初始化讀者、寫者佇列為0,初始化令牌資源、讀寫計數器資源的初始值為1*/ int readCount = 0; int writeCount = 0; semaphore read = 1; semaphore readCountSignal = 1; semaphore writeCountSignal = 1; reader() { while(true) { wait(read); //申請令牌 wait(readCountSignal); //申請讀者佇列計數器 if(!readCount) //如果讀者佇列為空,申請檔案資源 wait(fileSrc); readCount++; signal(readCountSignal); //釋放讀者計數器資源 signal(read); //釋放令牌 ... perform read operation //執行臨界區程式碼 ... wait(readCountSignal); //申請讀者計數器資源 readCount--; if(!readCount) //如果讀者佇列為空,釋放檔案資源 signal(fileSrc); signal(readCountSignal); //釋放讀者計數器資源 } } writer() { while(true) { wait(writeCountSignal); //申請寫者計數器資源 if(!writeCount) //如果寫者佇列為空則申請令牌 wait(read); writeCount++; signal(writeCountSignal); //釋放寫者計數器資源 wait(file); //申請檔案資源 ... perform write operation //執行臨界區程式碼 ... signal(fileSrc); //釋放檔案資源 wait(writeCountSignal); //申請寫者計數器資源 writeCount--; if(!writeCount) //如果寫者佇列為空則釋放令牌 signal(read); signal(writeCountSignal); //釋放寫者計數器資源 } }
1.優先順序相同。
2.寫者、讀者互斥訪問。
3.只能有一個寫者訪問臨界區。
4.可以有多個讀者同時訪問臨界資源。
具體實現:
1.設定file訊號量實現對臨界資源的互斥訪問。
2.設定計數器readCount實現多個讀者訪問臨界資源,通過設定訊號量readCountSignal實現對readCount計數器的互斥訪問。
3.設定訊號量keySignal實現讀者和寫者的公平競爭(令牌)。
4.設定訊號量OneSignal實現只有讀者佇列或寫者阻塞在keySignal(對令牌資源的訪問控制)。
/* 讀者佇列初始值為0,其他資源初始值為1*/
int readCount = 0;
semaphore keySignal = 1;
semaphore OneSignal = 1;
semaphore readCountSignal = 1;
reader()
{
while(true)
{
wait(keySignal); //申請令牌
wait(readCountSignal); //申請計數器資源
if(!readCount) //為零則申請檔案資源
wait(fileSrc);
readCount++;
signal(readCountSignal); //釋放計數器資源
signal(keySignale); //釋放令牌
...
perform read operation //執行臨界區程式碼
...
wait(readCountSignal); //申請計數器資源
readCount--;
if(!readCount) //為零則釋放檔案資源
signal(fileSrc);
signal(readCountSignal); //釋放讀者計數器資源
}
}
writer()
{
while(true)
{
wait(OneSignal); //申請令牌資源
wait(keySignal); //申請令牌
wait(fileSrc); //申請檔案資源
...
perform write operation //執行臨界區程式碼
...
signal(fileSrc); //釋放檔案資源
signal(keysignal); //釋放令牌
signal(OneSignal); //釋放令牌資源
}
}