核心態同步物件之「事件」

2021-05-31 22:05:26 字數 1566 閱讀 9599

事件是一種很常使用到的,用於同步的核心物件。

它分為兩種:<手動擋的>,<自動擋的>

手動擋:顧名思義,如果乙個事件啟用之後,你不顯式呼叫resetevent的話,那麼事件就一直處於啟用狀態。

自動擋:在任何乙個執行緒waitfor函式成功之後,該事件就會被重新調整為未啟用狀態。

手動擋的事件通常應用於這麼乙個場景:

你想象一下十一假期某天清晨的故宮,外面一票人現在等著開門,裡面一票人也忙著進行什麼調包文物,修建會館啊等利國利民的大事。(一群執行緒等待某些執行緒完成工作)。

等上面這些大事進行完成之後,門開了!(手動擋的事件現在被啟用)

伴隨著門口那些比如「媽!你在哪?」,「別擠啦!!!」,「我的鞋!!!」等多種多樣的喊叫聲,人民群眾開始有條不紊地進入故宮參觀(所有wait該事件的執行緒現在都結束了wait狀態進行各自的工作。)

參觀的基本原則就是只許看不許摸。(某遊客不滿道:「摸一下又不會懷孕的撒~~~」。)(如果涉及到共享資料區,那麼這麼執行緒必須都只能以唯讀的方式運算元據)

自動檔的則好說了,這就相當於每次故宮放進去乙個遊客後就關大門,直到這位遊客看爽了之後再把大門開啟放下乙個。

事件物件在使用上有什麼需要注意的呢?

有關於什麼死鎖什麼之類的我就不談了,在這裡我只說這樣乙個問題:

如果對乙個已經啟用的物件再呼叫setevent進行啟用,該api不返回錯誤,而且也沒有效果

來看一段坑爹的**:

handle g_hevent;

unsigned int __stdcall thread(void* pparam)

return 0;

}unsigned int __stdcall triger(void* pparam)

int _tmain(int argc, _tchar* argv)

你猜,

「hahahaha」

會列印出來幾個?

如果說,整個程式的執行是這麼乙個序列:

1. 執行緒1進入等待

2. 主線程啟用事件

3. 執行緒1列印後等待

4. 執行緒2啟用事件

5. 執行緒1列印

那明顯結論是兩個。

但是吧,你怎麼這麼保證不是這麼乙個序列?

1. 執行緒1等待

2. 主線程啟用事件

3. 執行緒2啟用事件

4. 執行緒1列印

有同學肯定會說了,在啟用事件的同時os可以檢視是否有執行緒正在等待,如果有等待的,則等待執行緒直接結束等待狀態。我說你太天真了。

再看這麼一段更坑爹的**:

handle g_hevent;

unsigned int __stdcall thread(void* pparam)

return 0;

}int _tmain(int argc, _tchar* argv)

這段**良好的證明了啟用事件後等待的執行緒不是立刻就調入cpu執行的。不信你就自己執行一下看看。

執行緒同步之事件物件

執行緒同步 讓執行緒協同步調,按照一定的先後次序來執行 當人工重置的事件得到通知時,等待該事件的所有執行緒均變為可排程執行緒。當乙個自動重置的事件得到通知時,等待該事件的執行緒中只有乙個執行緒變為可排程執行緒。參考 多執行緒與事件物件 多執行緒程式設計 13 多執行緒同步之 event 事件物件 i...

RT thread核心之事件

一 事件控制塊 在include rtdef.h中 ifdef rt using event flag defintions in event define rt event flag and 0x01 logic and define rt event flag or 0x02 logic or ...

執行緒同步 核心物件實現執行緒同步 事件核心物件

1 事件核心物件23 事件型別物件有兩種不同型別,手動重置和自動重置 4手動重置 當乙個手動重置物件被觸發時候,等待該物件的所有執行緒變為可排程。5自動重置 當乙個自動重置物件被觸發時,只有乙個等待該事件的執行緒會變為可排程67 下面是乙個建立事件核心物件的函式 8handle createeven...