8.3 經(jīng)典進程同步問題-讀寫者問題

問題描述

有讀者和寫者兩組并發(fā)進程,共享一個文件,當兩個或以上的讀進程同時訪問共享數(shù)據(jù)時不會產(chǎn)生副作用,但若某個寫進程和其他進程(讀進程或?qū)戇M程)同時訪問共享數(shù)據(jù)時則可能導(dǎo)致數(shù)據(jù)不一致的錯誤。因此要求:

  • 允許多個讀者可以同時對文件執(zhí)行讀操作;
  • 只允許一個寫者往文件中寫信息;
  • 任一寫者在完成寫操作之前不允許其他讀者或?qū)懻吖ぷ鳎?/li>
  • 寫者執(zhí)行寫操作前,應(yīng)讓已有的讀者和寫者全部退出。

問題分析

  1. 關(guān)系分析。由題目分析讀者和寫者是互斥的,寫者和寫者也是互斥的,而讀者和讀者不存在互斥問題。

  2. 整理思路。兩個進程,即讀者和寫者。寫者是比較簡單的,它和任何進程互斥,用互斥信號量的P操作、V操作即可解決。讀者的問題比較復(fù)雜,它必須實現(xiàn)與寫者互斥的同時還要實現(xiàn)與其他讀者的同步,因此,僅僅簡單的一對P操作、V操作是無法解決的。那么,在這里用到了一個計數(shù)器,用它來判斷當前是否有讀者讀文件。當有讀者的時候?qū)懻呤菬o法寫文件的,此時讀者會一直占用文件,當沒有讀者的時候?qū)懻卟趴梢詫懳募M瑫r這里不同讀者對計數(shù)器的訪問也應(yīng)該是互斥的。

  3. 信號量設(shè)置。首先設(shè)置信號量count為計數(shù)器,用來記錄當前讀者數(shù)量,初值為0; 設(shè)置mutex為互斥信號量,用于保護更新count變量時的互斥;設(shè)置互斥信號量rw用于保證讀者和寫者的互斥訪問。

讀進程優(yōu)先解決方案

當存在讀進程時,寫操作將被延遲,并且只要有一個讀進程活躍,隨后而來的讀進程都將被允許訪問文件。描述如下:

int count=0;  //用于記錄當前的讀者數(shù)量
semaphore mutex=1;  //用于保護更新count變量時的互斥
semaphore rw=1;  //用于保證讀者和寫者互斥地訪問文件
writer () {  //寫者進程
    while (1){
        P(rw); // 互斥訪問共享文件
        Writing;  //寫入
        V(rw) ;  //釋放共享文件
    }
}

reader () {  // 讀者進程
    while(1){
        P (mutex) ;  //互斥訪問count變量
        if (count==0)  //當?shù)谝粋€讀進程讀共享文件時
            P(rw);  //阻止寫進程寫
        count++;  //讀者計數(shù)器加1
        V (mutex) ;  //釋放互斥變量count
        reading;  //讀取
        P (mutex) ;  //互斥訪問count變量
        count--; //讀者計數(shù)器減1
        if (count==0)  //當最后一個讀進程讀完共享文件
            V(rw) ;  //允許寫進程寫
        V (mutex) ;  //釋放互斥變量 count
    }
}

寫進程優(yōu)先解決方案

讀進程優(yōu)先解決方案會導(dǎo)致寫進程可能長時間等待,且存在寫進程“餓死”的情況。下面描述寫進程有限解決方案:

int count = 0;  //用于記錄當前的讀者數(shù)量
semaphore mutex = 1;  //用于保護更新count變量時的互斥
semaphore rw=1;  //用于保證讀者和寫者互斥地訪問文件
semaphore w=1;  //用于實現(xiàn)“寫優(yōu)先”

writer(){
    while(1){
        P(w);  //在無寫進程請求時進入
        P(rw);  //互斥訪問共享文件
        writing;  //寫入
        V(rw);  // 釋放共享文件
        V(w) ;  //恢復(fù)對共享支件的訪問
    }
}

reader () {  //讀者進程
    while (1){
        P (w) ;  // 在無寫進程請求時進入
        P (mutex);  // 互斥訪問count變量

        if (count==0)  //當?shù)谝粋€讀進程讀共享文件時
            P(rw);  //阻止寫進程寫

        count++;  //讀者計數(shù)器加1
        V (mutex) ;  //釋放互斥變量count
        V(w);  //恢復(fù)對共享文件的訪問
        reading;  //讀取
        P (mutex) ; //互斥訪問count變量
        count--;  //讀者計數(shù)器減1

        if (count==0)  //當最后一個讀進程讀完共享文件
            V(rw);  //允許寫進程寫

        V (mutex);  //釋放互斥變量count
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容