2014-03-13 127 views
1

我在使用信號量進行進程同步時遇到了困難。基本上,我沒有看到中斷會如何破壞程序,並構建場景來解決問題。下面是我堅持了幾天的一個問題。請幫忙。提前致謝!關於使用信號量進行線程同步的示例

描述:「H2O」問題。

hReady()和oReady()函數「生成」H和O.每個H線程和O線程執行hReady()和oReady()。準備完成兩個H和一個O後,其中一個程序必須調用makewater()。解決方案應避免飢餓和忙碌等待。還假設線程喚醒的FIFO策略。

方法1:這種方法的任何問題? (答案是肯定的,我能理解爲什麼。)

int numHydrogen = 0; 
sema_t pairOfHydrogen = 0; 
sema_t oxygen = 0; 

void hReady() { 
    numHydrogen ++;    // I'm assuming here should have a mutex 
    if ((numHydrogen % 2) == 0) { 
    signal(pairOfHydrogen); 
    } 
    wait(oxygen); 
} 

void oReady() { 
    wait(pairOfHydrogen); 
    makeWater(); 
    signal(oxygen); 
    signal(oxygen); 
} 

方法2:有什麼問題嗎? (答案是肯定的,但我不明白爲什麼還有如何構建一個特定的場景。?)

sema_t hPresent = 0; 
sema_t waitForWater = 0; 

void hReady() { 
    signal(hPresent); 
    wait(waitForWater); 
} 

void oReady() { 
    wait(hPresent);  // It seems something wrong here. I'm not sure why 
    wait(hPresent);  // Also here. Why? 
    makeWater(); 
    signal(waitForWater); 
    signal(waitForWater); 
} 

方法3:在方法2.任何問題假設LIFO線程喚醒窗口? (也是,但是爲什麼呢?在這個問題中,喚醒策略是如何發揮作用的?)

有沒有什麼簡單的方法可以解決類似的問題?應該怎麼考慮構建場景?再次感謝您的幫助!

+0

你有什麼問題?另外,你的方法#2是可怕的錯誤。一個人不應該連續兩次等待信號量。這是一個死鎖的可愛牀。 –

+0

我未能構建場景來描述潛在的問題。特別是在方法2和3中,線程喚醒策略如何影響?在我看來,O線始終可以找到2 H來製造水。 – Yuki

+0

你能否展示更多你的代碼?我沒有看到你是如何開始線程和在哪裏。它們很重要,我感覺到僵局。 –

回答

1

方法1

方案:hReadyoReady之前推出。

hReady線程會發生什麼:

  1. 構建一個H
  2. 我們有一對H + - >都能跟得上(都沒有信號)
  3. 等待O(阻塞)

oReady線程會發生什麼:

  1. 等待H2(沒有 - >阻塞)

所以你的2個演員被阻止,因爲hReady只產生一個H而不是2,並等待一個永遠不會到來的O(因爲他也在等待)。 也如您所見,numHydrogen可能需要R/W保護。

方法2

幾乎相同的情況下:當您啓動hReady你被封鎖在waitForWater。 先等待在oReady被解鎖,但第二個將永遠持續下去,因爲你沒有信號waitForWater

我不明白approach3雖然...

+0

我可能沒有清楚地描述問題......原本可能存在很多O和H.它們每個都可以啓動一個線程(oReady( )或hReady())。對運行/阻塞線程的總數沒有限制。所以,有可能2個獨立的H發起2個線程,並且每個都被單獨等待O來阻止...... – Yuki

+1

好吧我不理解它那種抱歉。 對我來說,第一種方法的主要問題是'numHydrogen'沒有受到競爭訪問的保護。因此2個H線程可能同時計算'numHydrogen%2 == 0'。 如果考慮線程喚醒的FIFO策略,我無法看到第二個錯誤。然而,在LIFO政策中,如果H的生產速度比O的生產速度快,則第一個阻止的H線程可能永遠不會喚醒。 – Coconop

+0

對於延遲,抱歉。你對第二點是對的,我早前在課堂上確定了答案。如果使用FIFO,FIFO隊列中阻塞的H-O對總是會在某個點獲得另一個H,並形成水。然而,後進先出並非如此。只要到達的訂單不是[2 * H和1 * O](可能是H-O-H-O ...或H-O-O -...或者任何不是2H1O),就不會形成水。你的文章非常鼓舞人心,非常感謝! – Yuki