操作系统(二十六)读者写者问题
2.3.9 讀者寫者問題
? 讀者寫者問題是十分經典的進程同步的問題,問題描述如下:讀進程與寫進程共享文件,但是寫進程必須與其他進程互斥發生。
根據以上的題目要求我們可以得出一些互斥關系:寫進程與寫進程互斥,讀進程與寫進程互斥
??我們可以設置一個互斥信號量rw來實現對互斥信號的共享訪問
semaphore rw=1; //用于實現對共享文件的互斥訪問writer (){while(1){P(rw); //寫之前“加鎖”寫文件…V(rw); //寫完了“解鎖”} }reader (){ while(1){P(rw); //讀之前“加鎖”讀文件…V(rw); //讀完了“解鎖”} }? 但是這樣簡單的上鎖解鎖會導致讀文件不能同時進行,就像我們進房間,打開門之后接著關上了門,后面的人當然沒辦法繼續進來了。按照日常經驗,開門應該有第一個人完成而關門應該有最后一個人完成,于是我們再次引入count計數器,記錄正在讀的進程數。
semaphore rw=1; //用于實現對共享文件的互斥訪問 int count = 0; //記錄當前有幾個讀進程在訪問文件 semaphore mutex = 1;//用于保證對count變量的互斥訪問writer (){while(1){P(rw); //寫之前“加鎖”寫文件…V(rw); //寫完了“解鎖”} }reader (){while(1){if(count==0) //由第一個讀進程負責P(rw); //讀之前“加鎖”count++; //訪問文件的讀進程數+1讀文件…count--; //訪問文件的讀進程數-1if(count==0) //由最后一個讀進程負責V(rw); //讀完了“解鎖”} }? 這樣做我們又會發現問題,如果兩個讀進程同時在count++前訪問的話,P(rw)會這執行兩次,那么第二個讀進程會被阻塞。這是由于對count的檢查以及賦值沒有一氣呵成(缺乏原子性)所以我們需要再來一個變量mutex實現對count互斥訪問。
semaphore rw=1; //用于實現對共享文件的互斥訪問 int count = 0; //記錄當前有幾個讀進程在訪問文件 semaphore mutex = 1;//用于保證對count變量的互斥訪問writer (){while(1){P(rw); //寫之前“加鎖”寫文件…V(rw); //寫完了“解鎖”} }reader (){while(1){P(mutex); //各讀進程互斥訪問countif(count==0) //由第一個讀進程負責P(rw); //讀之前“加鎖”count++; //訪問文件的讀進程數+1V(mutex);讀文件…P(mutex); //各讀進程互斥訪問countcount--; //訪問文件的讀進程數-1if(count==0) //由最后一個讀進程負責V(rw); //讀完了“解鎖”V(mutex);} }? 但是按照上述的代碼來執行的話,寫進程的操作總會被讀進程的到來而阻塞,可能會導致讀進程饑餓,我們再來添加一個互斥信號量w來實現公平讀寫(先來先服務)
semaphore rw=1; //用于實現對共享文件的互斥訪問 int count = 0; //記錄當前有幾個讀進程在訪問文件 semaphore mutex = 1; //用于保證對count變量的互斥訪問 semaphore w = 1; //用于實現公平writer (){while(1){P(w);P(rw);寫文件…V(rw);V(w);} }reader (){while(1){P(w);P(mutex);if(count==0)P(rw);count++;V(mutex);V(w);讀文件…P(mutex);count--;if(count==0)V(rw);V(mutex);} }??讀者-寫者問題其核心思想在于設置了一個計數器 count 用來記錄當前正在訪問共享文件的讀進程數。我們可以用count 的值來判斷當前進入的進程是否是第一個/最后一個讀進程,從而做出不同的處理。
? 另外,對 count 變量的檢查和賦值不能一氣呵成導致了一些錯誤,如果需要實現“一氣呵成”,自然應該想到用互斥信號量。
總結
以上是生活随笔為你收集整理的操作系统(二十六)读者写者问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2021中国餐饮营销力白皮书
- 下一篇: 一些独到的识人技巧