setevent

setevent是一種Win32系統編程的事件API。

基本信息

簡介

CEvent::SetEvent

BOOL SetEvent(HANDLE hEvent);

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

Win32系統編程API,用於執行緒間通信。

說明

設定事件的狀態為有標記,釋放任意等待執行緒。如果事件是手工的,此事件將保持有標記直到調用ResetEvent,這種情況下將釋放多個執行緒;如果事件是自動的,此事件將保持有標記,直到一個執行緒被釋放,系統將設定事件的狀態為無標記;如果沒有執行緒在等待,則此事件將保持有標記,直到一個執行緒被釋放。

用法

執行緒中SetEvent及WaitForSingleObject用法

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

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

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

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

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

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

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

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

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

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

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

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

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

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

使用環境

Windows NT/2000:需要3.1或更高版本

Windows 95/98:需要Windows 95或更高版本

頭檔案:定義在Winbase.h;需要包含 Windows.h。

導入庫:user32.lib

Unicode:在Windows NT/2000中,以 Unicode 和 ANSI 執行

一個Event被創建以後,可以用OpenEvent()API來獲得它的Handle,用CloseHandle()

來關閉它,用SetEvent()或PulseEvent()來設定它使其有信號,用ResetEvent()

來使其無信號,用WaitForSingleObject()或WaitForMultipleObjects()來等待

其變為有信號.

PulseEvent()是一個比較有意思的使用方法,正如這個API的名字,它使一個Event

對象的狀態發生一次脈衝變化,從無信號變成有信號再變成無信號,而整個操作是原子的.

對自動復位的Event對象,它僅釋放第一個等到該事件的thread(如果有),而對於

人工復位的Event對象,它釋放所有等待的thread.

2.WaitForSingleObject的用法

參數hHandle是一個事件的句柄,第二個參數dwMilliseconds是時間間隔。如果時間是有信號狀態返回WAIT_OBJECT_0,如果時間超過dwMilliseconds值但時間事件還是無信號狀態則返回WAIT_TIMEOUT。

hHandle可以是下列對象的句柄:

Change notification

Console input

Event

Job

Memory resource notification

Mutex

Process

Semaphore

Thread

Waitable timer

WaitForSingleObject函式用來檢測hHandle事件的信號狀態,當函式的執行時間超過dwMilliseconds就返回,但如果參數dwMilliseconds為INFINITE時函式將直到相應時間事件變成有信號狀態才返回,否則就一直等待下去,直到WaitForSingleObject有返回直才執行後面的代碼。在這裡舉個例子:

先創建一個全局Event對象g_event:

CEvent g_event;

在程式中可以通過調用CEvent::SetEvent設定事件為有信號狀態。

下面是一個執行緒函式MyThreadPro()

在這個執行緒函式中只有設定g_event為有信號狀態時才執行下面的for循環,因為g_event是全局變數,所以我們可以在別的執行緒中通過g_event. SetEvent控制這個執行緒。

還有一種用法就是我們可以通過WaitForSingleObject函式來間隔的執行一個執行緒函式的函式體

在這個執行緒函式中可以可以通過設定MT_INTERVAL來控制這個執行緒的函式體多久執行一次,當事件為無信號狀態時函式體隔MT_INTERVAL執行一次,當設定事件為有信號狀態時,執行緒就執行完畢了。

相關詞條

相關搜尋

熱門詞條

聯絡我們