SetEvent()和ResetEvent()

一、綜述:

SetEvent()使當前事件對象處於有信號狀態,當前的這個線程可以繼續執行。
ResetEvent()是當前事件對象處於無信號狀態,當前的線程處於睡眠狀態,不能執行。

 

設置爲TRUE就是有信號狀態CreateEvent(,,TRUE,)  = CreateEvent(,,FALSE,) + SetEvent() 

CreateEvent(,,TRUE,):是設置事件對象的起始狀態爲有信號;

CreateEvent(,,FALSE,) :是設置事件對象的起始狀態爲無信號;

SetEvent():手動設置事件對象的狀態爲有信號 。

 

二、詳細介紹:

SetEvent()設置事件爲有信號狀態時,線程就執行完畢了!

BOOL SetEvent(HANDLE hEvent);

其中hEvent表示句柄,返回值:如果操作成功,則返回非零值,否則爲0。

說明

設置事件的狀態爲有標記,釋放任意等待線程。

如果事件是手工的,此事件將保持有標記直到調用ResetEvent,這種情況下將釋放多個線程;

如果事件是自動的,此事件將保持有標記,直到一個線程被釋放,系統將設置事件的狀態爲無標記;

如果沒有線程在等待,則此事件將保持有標記,直到一個線程被釋放。

用法

線程中SetEvent及WaitForSingleObject用法

SetEvent/ResetEvent分別將EVENT置爲這兩種狀態分別是發信號與不發信號。

WaitForSingleObject()等待,直到參數所指定的OBJECT成爲發信號狀態時才返回,OBJECT可以是EVENT,也可以是其它內核對象。 當你創建一個線程時,其實那個線程是一個循環,不像上面那樣只運行一次的。這樣就帶來了一個問題,在那個死循環裏要找到合適的條件退出那個死循環,那麼是怎麼樣實現它的呢?在Windows裏往往是採用事件的方式,當然還可以採用其它的方式。在這裏先介紹採用事件的方式來通知從線程運行函數退出來,它的實現原理是這樣,在那個死循環裏不斷地使用WaitForSingleObject函數來檢查事件是否滿足,如果滿足就退出線程,不滿足就繼續運行。當在線程裏運行阻塞的函數時,就需要在退出線程時,先要把阻塞狀態變成非阻塞狀態,比如使用一個線程去接收網絡數據, [1]  同時使用阻塞的SOCKET時,那麼要先關閉SOCKET,再發送事件信號,纔可以退出線程的。

當然我感覺重要應用方面還是用來鎖定,實現所謂的pv功能。

在調用的過程中,所有線程都可以在一個等待函數中指定事件對象句柄。當指定的對象的狀態被置爲有信號狀態時,單對象等待函數將返回。

對於多對象等待函數,可以指定爲任意或所有指定的對象被置爲有信號狀態。當等待函數返回時,等待線程將被釋放去繼續運行。

初始狀態在bInitialState參數中進行設置。使用SetEvent函數將事件對象的狀態置爲有信號狀態。使用ResetEvent函數將事件對象的狀態置爲無信號狀態。

當一個手動復原的事件對象的狀態被置爲有信號狀態時,該對象狀態將一直保持有信號狀態,直至明確調用ResetEvent函數將其置爲無符號狀態。

當事件的對象被置爲有信號狀態時,任意數量的等待中線程,以及隨後開始等待的線程均會被釋放。

當一個自動復原的事件對象的狀態被置爲有信號狀態時,該對象狀態將一直保持有信號狀態,直至一個等待線程被釋放;系統將自動將此函數置爲無符號狀態。如果沒有等待線程正在等待,事件對象的狀態將保持有信號狀態。

多個進程可持有同一個事件對象的多個句柄,可以通過使用此對象來實現進程間的同步。下面的對象共享機制是可行的:

·在CreateEvent函數中,lpEventAttributes參數指定句柄可被繼承時,通過CreateProcess函數創建的子進程繼承的事件對象句柄。

·一個進程可以在DuplicateHandle函數中指定事件對象句柄,從而獲得一個複製的句柄,此句柄可以被其它進程使用。

·一個進程可以在OpenEvent或CreateEvent函數中指定一個名字,從而獲得一個有名的事件對象句柄。

使用CloseHandle函數關閉句柄。當進程停止時,系統將自動關閉句柄。當最後一個句柄被關閉後,事件對象將被銷燬。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章