最近在看一些同步對象模擬的東東,特別對在Windows下如何模擬條件變量折騰了好久。函數
微軟有一個頗有意思的同步對象,某種程度上和Linux的條件變量很類似。但秉承微軟一向的做風,有些地方設計的又有點怪異。Event經過函數CreateMutex建立,能夠分爲手動模式和自動模式兩種模式,兩種模式下表現迥異。和其餘同步對象同樣,在WaitForSingleObject或者WaitForMultipleObjects等待激發。激發(取消激發)法有3個函數SetEvent,ResetEvent,PulseEvent根據模式不一樣給出說明以下表:學習
自動模式spa |
手動模式線程 |
|
SetEvent設計 |
放過一個等待線程,對象 將Event調爲激發態,放過一個等待線程,然後自動調回非激發態ip |
一直放過等待ci 將Event調爲激發態,同步 |
ResetEventit |
無用 |
中止放過線程 將Event調爲非激發態 |
PulseEvent |
一次放過一個等待的線程,在這種模式下等同與SetEvent |
放過全部的等待的線程一次, 將Event調爲激發態,放過全部的等待的線程一次,而後調回非激發態 |
因此綜合看來大體看來Event大體有幾種使用模式,
自動模式下的WaitForSingleObject + SetEvent,(幹一件過後)開一次們放過一個。
手段模式下的WaitForSingleObject + SetEvent + ResetEvent,SetEvent後打開大門,放一批人進來,而後用ResetEvent手動關閉大門。
手段模式下的WaitForSingleObject + PulseEvent ,(幹一件過後),廣播給全部等在門外的人,讓他們進來。
其實你把這些功能組合起來看,Event這是個頗有意思的東東並且萬分強大,某種程度也知足了咱們不少同步的需求。
條件變量是一個更加複雜的東東,他在等待的基礎上又糅合了等待條件。條件變量的對象用函數初始化,在pthread_cond_wait函數上等待,pthread_cond_signal激發後,解除一個等待線程的阻塞,pthread_cond_broadcast廣播解除全部等待線程的阻塞(一次)。
看了上面的說明,應該能夠發現Windows的Event和pthread的條件變量很像,
某種程度上,自動模式Event的SetEvent很像條件變量的pthread_cond_signal,手動模式的Event的PulseEvent很像廣播pthread_cond_broadcast,
但你要直接拿Event來模擬條件變量又不行了,爲啥。由於你不可能讓一個Event對象同時擁有手動觸發和自動觸發模式,你奈他何。也許若是微軟把PulseEvent在手動模式的功能放到自動模式,會讓你們移植的時候更加舒服一點。
關於條件變量在Windows的模擬,若是你們有興趣並且有關心一下ACE或者pthread-win32或者BOOST(BOOST是學習pthread-win32的),但要看懂的pthread-win32模擬實在是一個蛋疼的事情。
而由於通常狀況下你們也不會混用pthread_cond_broadcast和pthread_cond_signal,因此實現一個簡單一點的模擬是否是更好一點?
(本身後面的模擬發現Event用於模擬條件變量仍是有必定的麻煩的,後面專門寫文章說明吧。)