2014-02-05 22 views
0

我不明白在第二個讀寫器問題的通用解決方案中讀者過程開始時最外層互斥體的目的是什麼。第二讀者 - 作者pr * blem - 爲什麼讀者需要第三個互斥體

爲了說明這一點,我將從適當的維基百科條目(link)發佈代碼。我在說mutex_3:

READER 
    P(mutex_3); 
    P(r); 
     P(mutex_1); 
     readcount := readcount + 1; 
     if readcount = 1 then P(w); 
     V(mutex_1); 
    V(r); 
    V(mutex_3); 

    reading is performed 

    P(mutex_1); 
    readcount := readcount - 1; 
    if readcount = 0 then V(w); 
    V(mutex_1); 

我能想到的唯一答案就是阻止新讀者涌入。但我認爲除了它的核心功能之外,它已經完成了下一個互斥體,即r。我錯了嗎?

回答

0

我看到這個問題被問了一段時間後,但我想我會只是發佈答案,以防萬一在未來幫助其他人。

我們使用互斥鎖來保護共享資源不被多個線程同時訪問。在mutex_3的情況下,如果您查看緊跟在P(mutex_3)之後的代碼,我們會看到我們要保護的共享資源是信號量r。因此,通過互斥鎖確保只有一個閱讀器可以在任何時候執行P(r)和V(r)之間的代碼段。

要明白爲什麼這個互斥量很重要,我們還需要考慮作者的代碼。維基百科:

撰稿人

P(mutex_2); 
writecount := writecount + 1; 
if writecount = 1 then **P(r)**; <-- Writer waits on semaphore r 
V(mutex_2); 

P(w); 
writing is performed 
V(w); 

P(mutex_2); 
writecount := writecount - 1; 
if writecount = 0 then V(r); 
V(mutex_2); 

的關鍵部分要注意的是在大膽。正如你所看到的,作者和讀者都在信號量r上調用P(r)。在這種情況下,不清楚誰的呼叫首先成功。我們假設作者在調用P(r)時沒有得到任何優先權(如果它確實不需要mutex_3)。

但是,第二個讀者 - 作者問題的問題陳述指出作者應該儘快開始。如果按先來先服務的原則進行調度,那麼在上述情況下,如果讀者先設法調用P(r),則讀者的調用成功。然後作者被推遲了,我們不想要。

因此,解決方案是在讀卡器的設置代碼(mutex_3)周圍放置一個互斥鎖。現在,當讀者調用V(r)時,不能有任何其他閱讀器在等待r,因爲其他閱讀器需要獲取mutex_3才能調用P(r),但當前閱讀器持有mutex_3!然而,可以有一個作家等待r,所以在這種情況下,作者對P(r)的呼叫總是儘快成功,因爲它是唯一一個等待r的人。