2010-05-25 64 views
0

我希望有兩個線程。第一個線程1偶爾會調用下面的僞功能:如何多線程呢?

void waitForThread2() { 
    if (thread2 is not idle) { 
    return; 
    } 
    notifyThread2IamReady(); // i.e. via 1st condition variable 
    Wait for thread2 to finish exclusive access. // i.e. via 2nd condition variable. 
} 

第二個線程2是永遠在下面的僞循環:

for (;;) { 
    Notify thread1 I am idle. 
    Wait for thread1 to be ready. // i.e. via 1st condition variable. 
    Notify thread1 I am exclusive. 
    Do some work while thread1 is blocked. 
    Notify thread1 I am busy. // i.e. via 2nd condition variable. 
    Do some work in parallel with thread1. 
} 

什麼是寫這使得兩個線程1和線程是最好的方式在有多個內核的機器上儘可能地保持忙碌。我想避免在一個線程中的通知和另一個線程的檢測之間的長時間延遲。我試過使用pthread條件變量,但發現thread2正在執行'notify thread1 I busy'和while()onS2IsExclusive()中的waitForThread2()循環之間的延遲可能高達幾乎一秒的延遲。然後我嘗試使用一個易變的sig_atomic_t共享變量來控制它,但是出了問題,所以我不能正確地做到這一點。

+4

你會過得更好告訴人們,你實際上是試圖解決,而不是要求他們執行你已經設想了一個解決問題的... – 2010-05-25 02:13:47

+0

僞代碼並沒有太大的意義。你如何通知另一個線程你忙?爲什麼?此外,你在這裏關注線程;通常,您需要同步數據。你同步哪些數據,以及你的並行操作如何? – WhirlWind 2010-05-25 02:16:45

+0

如果你的condvars正在採取任何行動,你正在做的事情非常錯誤。此外,要做的規範是鎖定數據結構,而不是「通知其他線程」;後者不會縮放。 – 2010-05-25 02:28:53

回答

1

我看起來像你試圖做一個會合(一個短期來自阿達)。

第二個線程是坐着,等待第一個線程調用它,那麼它馬上做了一些工作,而第一個線程等待,和第一線後,一些更多的工作就完成了。

第一個線程正在「調用」第二個線程 - 如果第二個線程無法接聽呼叫,立即超時。

阿達支持這種直接的語言,但假設移植到小梅是不是一種選擇...

這可能有三個信號量來實現。信號量1表示線程1已準備好會合。信號量2指示線程2已準備好退出。信號量3表示會合完成。

線程1:獲得信號1的默認值。

if Semaphore 2.acquire(timeout = 0) is successful # Thread 2 is ready 
    Semaphore 1.release() # Indicate I am ready 
    Semaphore 3.acquire() # Wait until the rendevous is complete. 
    Semaphore 3.release() 
    Semaphore 1.acquire() # Indicate I am not ready 
    Semaphore 2.release() # I am no longer using thread 2. 

Do concurrent work 

線程2:獲取信號量2的默認值。

Loop forever 
    Semaphore 3.acquire() # Indicate Rendevous is not complete. 
    Semaphore_2.release() # Indicate I am ready 
    Semaphore_1.acquire() # Wait for Thread 1 to be ready 
    Joint processing 
    Semaphore 1.release() # I am no longer using thread 1. 
    Semaphore 3.release() # Rendevous is complete. 
    Semaphore 2.acquire() # I am not ready 

Post-processing 

注意:從頭開始編寫,未經測試。看起來比我想象的要複雜得多;我錯過了什麼嗎?

+0

信號比使用條件變量和互斥鎖更高效嗎? – WilliamKF 2010-05-25 03:52:28

+0

更高效的代碼行?不知道。運行時效率更高?與其他所有開銷相比,我懷疑你能分辨出差異。如果代碼中沒有更好的地方進行優化,我會非常驚訝。 – Oddthinking 2010-05-25 11:54:32

3

好像你應該使用旗語發信號,而不是「而」循環閒置線程,等待出現一些狀況。空閒循環是不好的。

+0

空閒循環真的是要解釋這個想法,而不是真的以這種方式實施。我已經從問題中刪除了他們,因爲他們正在引起主要問題的分心。目前,這些是用條件變量實現的,沒有超時。 – WilliamKF 2010-05-25 03:53:56

1

勝於讓線程告訴對方「我很忙」或「我不忙」,再想想在你的對象線程上運行的數據方面。

如果有一些數據(比如,一個計數器)這兩個線程可能試圖同時改變,這意味着你需要一個互斥體存在。

當一個線程更改其他線程可能正在等待的共享數據狀態時,發出一個條件變量的信號通知它們。 (例如,如果生產者線程將數據添加到隊列中,它可能表示消費者可能正在等待的「dataAvailable」條件。)

+0

我認爲這是問題的核心。 – WhirlWind 2010-05-25 02:31:55