同步機制 「讀寫鎖「的實現

2021-07-26 03:10:54 字數 3848 閱讀 9390

同步機制——「讀寫鎖「

(pj.courtois, * f.heymans, and d.l.parnas* mble research laboratory brussels, belgium)

多程序同時訪問臨界區域(critical section)的問題可以看成兩類程序:讀者(readers)和寫者(writers)。多個讀者之間可以共享臨界區域,但是多個寫者之間必須互斥的訪問臨界區域。所以使用基本同步機制時有兩種情況需要解決:當讀者之間訪問臨界區域時,需要盡可能降低由基本同步機制帶來的時間延遲;當寫者出現時,相對與讀者需要盡可能早的訪問臨界區域。

關鍵字:互斥鎖,臨界區域,共享訪問資源

dijkstra、knuth和de bruijn都討論過作業系統必須保證對共享資源的互斥訪問的問題,他們使用「p(sem–)」和「v(sem++)」操作簡單的解決這個問題。我們認識到實際上訪問共享資源的程序有兩類:第一類程序叫「寫者(writers)」,此類程序之間直接必須互斥的訪問共享資源。第二類程序叫「讀者(readers)」,此類程序之間可以同時訪問共享資源。

對於讀者(readers),我們要求自己的解決方案要滿足讀者只有在寫者(writers)已經獲取共享資源後才會進入等待狀態,當寫者正在等待一部分讀者結束對共享資源的訪問時,另一部分已經結束對共享資源訪問的讀者也不應該進入等待狀態 。解決這種情況好像十分簡單,但是經驗告訴我們這並不容易。現有的眾多解決方案過於複雜,我們討論之後提出以下簡化的解決方案,希望碰到相似問題的人可以少走些彎路。結局方案見fig. 1。

fig. 1

integer readcount; (initial value = 0)

semaphore mutex, w; (initial value for both = 1)

reader

writer

p(mutex);

readcount = readcount + 1;

if readcount == 1 then p(w);

v(mutex);

p(w);

reading is performed……

writing is performed

p(mutex);

readcount = readcount - 1;

if readcount == 0 then v(w);

v(mutex);v(w);

注意w變數是乙個互斥訊號量(mutual exclusion semaphore),用於互斥讀者與寫者同時對臨界區域的訪問。對於讀者而言,只在「第乙個讀者進入」和「最後乙個讀者離開」臨界區域時才修改它,而被其他的讀者和寫者所忽略。mutex用於確保同一時刻只有乙個負責調節w的讀者存在。只有當所有讀者和所以寫者均未訪問臨界區域時,w才為正值。

對於寫者(writers),要求任一寫者必須和所有的讀者互斥的訪問共享資源,另外我們增加了乙個要求,一旦寫者準備訪問共享資源,要盡可能快的獲取對共享資源的訪問操作。這種情況的解決方案不同於「情況一」,因為增加的要求,當乙個寫者準備訪問共享資源時,已經結束對共享資源訪問的讀者必須等待寫者完成對共享資源的訪問,即使這時的寫者處於等待其他讀者完成訪問操作的過程中。對於「情況一」而言,當不停的存在讀者訪問共享資源時,寫者有可能處於一直無限等待的過程中。我們提出的解決方案是優先讓寫者訪問共享資源,且當存在寫者訪問共享資源時,允許讀者無限的等待寫者完成訪問。原則上,解決方案應該讓寫者優先訪問共享資源,而不是假設讀者會進入到v操作。另外,當多個程序等待乙個訊號量時,我們也無法**在v操作結束時哪乙個程序將被執行。我們提出的解決方案見figure 2。

fig. 2

integer readcount, writecount; (initial value = 0)

semaphore mutex1, mutex2, mutex3, w, r; (initial value = 1)

reader

writer

p(mutex3);

p(r);

p(mutex1);

readcount = readcount + 1;

if readcount == 1 then p(w);

v(mutex1);

v(r);

v(mutex3);p(mutex2);

writecount = writecount + 1;

if writecount == 1 then p(r);

v(mutex2);

p(w);

reading is done……

writing is performed

p(mutex1);

readcount = readcount - 1;

if readcount == 0 then v(w);

v(mutex1);v(w);

p(mutex2);

writecount = writecount - 1;

if writecount == 0 then v(r);

v(mutex2);

很容易留意到,fig. 2中的mutex1hew和fig. 1中的mutexw完全對應。r訊號量的臨界區域(critical section)的行為與fig.1中w保護共享資源(shared resource)的行為一致,第乙個寫者操作p(r)用來鎖住讀者的mutex1w區域。mutex2被用於寫者的作用類似與fig.1中mutex被用於讀者的作用。mutex3的存在是必要的,因為我們要最大程度保證寫者的優先性質。如果沒有mutex3,當出現乙個寫者和乙個以上的讀者同時等待v(r)被某個讀者完成的狀態時,我們不能保證寫者的優先性質。mutex3保證了讀者互斥的訪問「p(r)」和「v(r)」之間的**,使得最多存在乙個等待r的程序,v操作的結果是明確的。

以上的解決方案不適用於寫者為「fifo discipline」的領域。為了提供這樣的支援,我們必須進一步改善v操作,或者使用訊號量陣列來表示寫者的數量。

我們感謝卡內基梅隆大學(carnegie-mellon university)的a.n. habermann在這個**的早期版本中指出了乙個錯誤。

Linux 同步機制 讀寫鎖

讀寫鎖也叫 shared exclusive 鎖,也是一種同步機制。讀寫鎖有三種狀態 讀模式下加鎖,寫模式下加鎖,不加鎖。有如下的使用約定 讀模式共享,寫模式獨佔,適合讀頻率遠大於寫頻率的場景。這些api位於 pthread.h 下。initialize read write lock rwlock...

核心同步機制之自旋鎖 讀 寫鎖

自旋鎖 spin lock 是用來在多處理器環境中工作的一種特殊的鎖。如果核心控制路徑發現自旋鎖 開著 就獲取鎖並繼續自己的執行。相反,如果核心控制路徑發現由執行在另乙個cpu上的核心控制路徑 鎖著 就在一直迴圈等待,反覆執行一條緊湊的迴圈指令,直到鎖被釋放。自旋鎖與互斥鎖有點類似,只是自旋鎖不會引...

同步機制 互斥鎖

互斥鎖指代相互排斥,它是最基本的同步形式。互斥鎖用於保護臨界區,以保證任何時刻只有乙個執行緒在執行其中的 或者任何乙個時刻只有乙個程序在執行其中的 保護乙個臨界區的 的通常輪廓大體如下 lock the mutex 臨界區unlock the mutex posix互斥鎖被宣告為具有pthread ...