用訊號量解決同步互斥問題 讀者寫者問題

2021-10-06 03:47:16 字數 1467 閱讀 4459

os老師上課在講解讀者和寫者問題時,一般會按照三個層次展開講解。根據訊號量的分布和控制邏輯,大體可以將讀者-寫者問題按由易到難分成如下這三大類:

讀者優先,課本上的寫法屬於佔位後讀優先,與佔位前讀優先、絕對讀優先一起,均歸於此類;

讀寫公平,根據讀寫程序的到達先後順序嚴格執行fcfs排程;

寫優先,包括佔位前寫優先、佔位後寫優先和絕對寫優先。

本文將從這三類中選擇關鍵的例子以「註解+**」的形式按序剖析。

rw用於實現寫寫互斥,讀寫互斥,但也導致了讀讀互斥。

readercnt的相關操作在寫寫互斥和讀寫互斥的基礎上實現了讀讀不互斥,同時也實現了佔位後讀優先。

mutex1用於對readercnt的讀寫操作提供互斥保護。

int readercnt=0;

semaphore mutex1=1, rw=1;

reader()

writer()

w用於在寫的最外層再建立乙個父佇列,這樣rw的佇列中不會出現寫。不論之前到達了多少寫,任意首次到達的讀均能夠直接被放到rw首部,即"總能跳過所有寫"。待正在執行的寫程序退出後,立刻執行這個首次到達的讀,即讀佔位,從而實現佔位前優先。

int readercnt=0;

semaphore mutex1=1, rw=w=1;

reader()

writer()

q用於實現乙個讀和寫的fifo公共佇列,這個佇列中程序的順序與程序的到達次序一致,從而實現fcfs,即讀寫公平。

reader()中v(q)的位置很巧妙:首先,v(q)應在v(mutex1)之後,這是由對稱性決定的,因為p(q)恰好在p(mutex1)之前,這個對稱性一旦被破壞,會進一步使mutex1的功能也被破壞;另一方面,reading()允許並行執行,若把v(q)放到reading()之後將會破壞這一條件,使得讀不能並行。綜上,v(q)應放在第乙個v(mutex1)和reading()之間。

擴充套件:如果把這裡的reading()換成writing(),那麼v(q)的位置可以放到writing()之後,或者reader()的最末尾。因為writing()本來就不能並行,上段中的第二個位置約束不再成立。

int readercnt=0;

semaphore mutex1=1, rw=q=1;

reader()

writer()

類似地,readercnt和wpao實現佔位後優先,wpbo實現佔位前優先。

wpbo = write priority before occupation,wpao = write priority after occupation。

int readercnt=0, writercnt=0;

semaphore mutex1=mutex2=1, rw=wpbo=wpao=1;

reader()

writer()

訊號量解決讀者 寫者問題

有兩組併發程序 讀者和寫者,共享檔案f,要求 1 允許多個讀者同時對檔案進行讀操作 2 只允許乙個寫者對檔案進行寫操作 3 任何寫者在完成寫操作前不允許其他讀者或寫者工作 4 寫者在執行寫操作前,應讓已有的寫者和讀者全部退出 單純的引入訊號量並不能解決此問題,必須引入計數器readcount對讀程序...

訊號量的互斥同步

訊號量的互斥同步都是通過pv原語來操作的,我們可以通過註冊兩個訊號量,讓它們在互斥的問題上互動,從而達到同步。通過下面例項就可以很容易理解 include include include include include include define return if fail p if p typ...

訊號量 實現同步互斥

了解訊號量之前,要先了解臨界資源 同步與互斥的概念 1.臨界資源 在同一時間只能被乙個程序呼叫的資源,也稱互斥資源。2.同步 保證訪問的時序可控性,使呼叫資源的的順序合理。3.互斥 在程序呼叫臨界資源是,不同程序之間要競爭該資源,那麼乙個程序呼叫了該資源,另乙個程序無法再呼叫該資源的情形就叫互斥!4...