1. 程式人生 > >讀者寫者問題(讀者優先、寫者優先、公平競爭)

讀者寫者問題(讀者優先、寫者優先、公平競爭)

讀者優先:
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); //釋放令牌資源
     }
}