2015-06-01 104 views
0

我在程序中發現了一個錯誤,即同一個線程被喚醒兩次,以便讓另一個線程運行,從而導致意外行爲。在我的程序中,所有等待的線程都應該每回合運行一次。發生此錯誤是因爲我使用信號量來使線程等待。在信號量初始化爲0時,每個線程在其無限循環開始時調用down到信號量,並且主線程在for循環NThreads(線程數)次中調用up。有時,同一個線程將兩次調用up,並出現問題。保證喚醒所有線程,並且每個線程只有一次

正確處理這個問題的方法是什麼?是使用條件變量和廣播的方式來做到這一點?它會保證每一個線程都只喚醒一次嗎?什麼是其他可能的好方法?

+0

你的問題似乎含糊給我,但總的來說,是的,條件變量被用來測試如果一段代碼被允許運行。 – user2079303

+0

我不相信條件變量會自己幫助你,你可以喚醒一個線程或喚醒所有線程,但是這個Waker無法知道或控制哪個阻塞線程將被解除阻塞。不幸的是,我認爲你需要一個互斥量來控制喚醒/阻塞狀態。 – Segfault

+0

因爲您用c和C++標記了防止任何不重要的回覆的標記,因此您可以進行投票 – kfsone

回答

1

那麼,使用一個信號量數組,每個線程一個。如果您想讓線程數組只運行一次,請向每個信號量發送一個單位。如果你想要這些線程全部運行N次,則向每個信號量發送N個單位。

+0

非常簡單,而且效果很好! – xiver77

1

在windows上,您可以使用WaitForMultipleObjects從當前Nthread迭代中尚未運行的線程中選擇一個準備就緒的線程。

每個線程都應該有一個「準備就緒」事件來發出準備好的信號,以及一個「喚醒」事件發出「準備就緒」事件後等待。

在主線程循環(NThreads迭代的第1個循環)開始時,使用NThreads「就緒」事件的數組調用WaitForMultipleObjects

然後將線程的「喚醒」事件設置爲由WaitForMultipleObjects返回的「就緒」事件,並將其從「準備就緒」句柄數組中移除。這將保證已經運行的線程在下一次迭代中不會被WaitForMultipleObjects返回。

重複,直到最後一次迭代,你將調用WaitForMultipleObjects只有一個線程句柄的數組(我認爲這將工作,如果你打電話WaitForSingleObject)。

然後重新填充的來確定nthreads「準備」事件數組的下一個新來確定nthreads迭代。