2012-05-21 21 views
0

我有兩個線程;線程2爲線程1提供必要的數據,並且可以在線程1處理它的同時開始處理另一條數據,但如果線程1較慢(如果我知道「線程1讀取線程2同時寫入的內容「,我有兩種緩衝區而不是一種保護)。該代碼是下面:線程暫停,另一個線程繼續 - 有時會發生第二個事件

Thread 1: 
while(!shouldexit) 
{ 
    // some code 
    Thread1_Ready = true; 
    SuspendThread (Thread1_Handle); 
} 

Thread 2: 
while(!shouldexit) 
{ 
    while(!Thread1_Ready) 
    { 
     // do nothing 
    } 
    // some other code 
    ResumeThread(Thread1_Handle); 
} 

的問題是,有時內部線程2整個代碼發生比SuspendThread發生在線程1的結果更快是線程1保持暫停,直到線程2道次的又一循環。這導致一個數據沒有被線程1處理(不是很好,但在我的應用程序中是可以接受的),而且更嚴重的是,當停止按鈕觸發shouldexit = true時,線程1只是無限期地處於暫停模式。

兩個,我認爲可能的解決方案是行不通的兩種: 1 - 把Thread1_Ready = true;SuspendThread(Thread1_Handle);後(代碼Thread1_Ready = true;從未執行,很明顯) 2 - 放線SuspendThread(Thread1_Handle);從線程1至線程2的開始,就在// some other code之前,但是這會導致線程1重新進入主循環的延遲,並且這將是非常不可預測的。

這種情況可以以不同的方式解決嗎?

+0

你用什麼語言:

因爲樣品運行看起來像這將解決問題了嗎? – dbf

+0

繁忙的等待不是解決此問題的正確方法。學習如何使用正確的同步原語。 – usr

+0

dbf,我正在使用C++。 –

回答

2

您有一個經典的producer-consumer problem。標準(在99%的情況下)解決方案是一個受互斥體保護的隊列。在你的情況下,隊列大小是1,但是隊列語義仍然適用。

Thread 1: Lock queue, see that queue is empty, wait for queue full signal 
Thread 2: Produce data 
Thread 2: Lock queue, push data into queue (has now size 1), Unlock queue and wake up Thread 1 
Thread 2: Produce data 
Thread 2: Lock queue, see that queue is full, wait for queue space signal 
Thread 1: Wakes up, gets data, sends queue space signal 
+0

謝謝,看了文章,好像很容易理解。但是有一個問題 - 獲取/釋放一個互斥體是否是一個原子操作?否則,我需要一種方法來確保線程不會同時進入臨界區(帶有隊列的操作)。 –

+1

@fynjyzn:互斥鎖(互斥鎖的簡寫)鎖是一種保證原子操作的機制,所以是的,從獲取到釋放互斥鎖的順序是原子的。由於您使用的是C++,因此您可能需要查看Boost.Thread及其條件變量。 – thiton

相關問題