2014-01-28 57 views
4

我實現了一個簡單的ThreadPool,它使用std::list<Tasks> mTasks作爲任務列表。什麼能喚醒條件變量

所有線程等待上使用下面的代碼條件變量:

EnterCriticalSection(&mCriticalSection); 

while(mTasks.size() ==0) 
    SleepConditionVariableCS(&mConditionVariable,&mCriticalSection, INFINITE); 

直到有人增加了一些到列表中,然後其中一人被喚醒。

我用了一段時間來檢查任務列表是否爲空,儘管唯一被喚醒的方法是向列表中添加一個新任務(所以它不能爲空),我這樣做的原因是因爲在MSDN它寫成:

條件變量受虛假喚醒(那些不 有一個明確的喚醒相關)和被盜喚醒(另一個線程 管理喚醒線程之前運行)。因此,在睡眠操作返回 之後,您應該重新檢查謂詞(通常在while循環中)。

但那些虛假喚醒是什麼,喚醒我的變量是什麼?

+0

阻塞隊列邏輯也應該在這裏工作。 – Nawaz

+0

我已經添加了'winapi'標籤,但是其他操作系統也會發生虛假喚醒。 – icabod

+0

@Nawaz我不理解你的評論 – OopsUser

回答

2

當我在大學學習時,我對這個話題的理解是,從性能的角度來看,實施100%安全的條件變量本來就太昂貴了。

spurious wakeups維基百科頁面有從大衛R. Butenhof(的Programming with POSIX Threads作者)報價說:

這意味着,當你等待條件變量,等待可能 (偶爾)回報當沒有線程專門廣播或 表示該條件變量。虛假喚醒可能聽起來很奇怪,但在某些多處理器系統上,使得條件完全喚醒可能會大大減緩所有條件變量 的操作。導致虛假喚醒比賽情況應 認爲是罕見的

while循環檢查的條件是一個很好的做法,一定會避免這個問題。

有關更多關於爲什麼會發生這種情況的詳細信息,我很抱歉,但我無法提供此類見解。

1

我認爲問題在於多處理器系統中多個處理器之間的同步問題。

爲了儘可能保持條件變量的輕量級實現,使用某些線程基元,儘管線程安全,但只有實際調用一個時,纔會導致條件變量註冊兩個樣式調用。這是一種罕見的情況,相反,通過處理這種情況來降低效率,設計人員會將問題推送到用戶代碼中,如果它可能會影響到您,則只需要擔心它。