2010-10-18 66 views
4

當使用boost::conditional_variable,ACE_Conditional或直接pthread_cond_wait時,是否有任何等待本身的開銷?這是更具體的問題那麻煩是:有條件的等待開銷

  1. 等待的線程是不定期之後,等待到期之前將其安排回來,然後再不定期或將留到不定期的信號?
  2. wait定期獲取互斥鎖嗎?在這種情況下,我猜測每次迭代會浪費系統調用的一些CPU時間來鎖定和釋放互斥鎖。它是不斷地獲取和釋放互斥體?
  3. 此外,信號和從wait返回之間需要多少時間?

Afaik,當使用信號量時,獲取調用的響應性取決於調度程序的時間片大小。它如何在pthread_cond_wait中工作?我認爲這是平臺依賴。我對Linux更感興趣,但如果有人知道它在其他平臺上如何工作,它也會有所幫助。

還有一個問題:是否有任何額外的系統資源分配給每個條件?我不會在我的代碼中創建30000個互斥體,但是我應該擔心使用同一個互斥體的30000個條件?

回答

5

下面是寫在pthread_cond手冊頁:

pthread_cond_wait原子解鎖互斥量及等待條件變量cond進行通知。線程執行被暫停,並且不消耗任何CPU時間,直到條件變量被髮送信號。

所以從這裏我回答問題如下:

  1. 的等待線程將不會被安排回等待是信號或取消之前。
  2. 沒有定期的互斥量收購。在等待返回之前,互斥鎖僅被重新獲取一次。
  3. 由於互斥鎖釋放,信號和等待返回之間的時間與線程調度的時間類似。

關於資源,同一個人網頁上:

在LinuxThreads實現,沒有資源與條件變量相關聯,從而pthread_cond_destroy實際上什麼也不做,除了檢查的條件沒有等待線程。

更新:我挖成的pthread_cond_ *函數來源和行爲如下:

  1. 所有在Linux中的並行線程條件語句使用futex實現。
  2. 當一個線程調用wait時,它被暫停和未預定。線程ID插入等待線程列表的尾部。
  3. 當一個線程調用signal時,列表頭部的線程被重新調度。 因此,喚醒與調度程序一樣高效,不佔用OS資源,唯一的內存開銷就是等待列表的大小(請參閱futex_wake函數)。
1

如果變量已經處於「錯誤」狀態,則只能調用pthread_cond_wait。由於它總是等待,所以總會有與將當前線程置於睡眠和切換相關的開銷。

當線程未計劃時,它不計劃。它不應該使用任何資源,但理論上操作系統當然可以被嚴重地執行。在信號之前允許重新獲得互斥體,甚至是返回(這就是爲什麼你必須仔細檢查條件),但是操作系統將被實現,所以這不影響性能,如果它發生在所有。它不是自發​​發生的,而是爲了迴應另一個可能不相關的信號。

30000 mutexes不應該是一個問題,但有些操作系統可能有30000個睡眠線程的問題。

+0

感謝您的回答。我需要澄清 - 在等待線程未計劃之後,是否會在等待過期之前重新安排計劃,然後再次取消計劃,否則它將保持未計劃狀態直至發出信號? – FireAphis 2010-10-19 06:26:43

+0

@Fire:我不確定你的意思是「過期」。你需要像'while(!condition())pthread_cond_wait(...);'那樣調用函數,其中'condition'是任何布爾必須是'true'來繼續執行,所以如果'cond_wait'提前返回,它再次。但正如我所說,許多操作系統從來不會這樣做,即使他們這樣做,通常也不是問題。如果你有一個超時,那麼表單是'while(!condition()&& pthread_cond_timedwait(...)!= ETIMEDOUT);'。 – Potatoswatter 2010-10-19 15:41:05