事件對象就像一個開關:它只有兩種狀態---開和關。當一個事件處於”開”狀態,我們稱其爲”有信號”否則稱爲”無信號”。可以在一個線程的執行函數中創建一個事件對象,然後觀察它的狀態,如果是”無信號”就讓該線程睡眠,這樣該線程佔用的CPU時間就比較少。
產生事件對象的函數如下:
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes, // SD
BOOL bManualReset, // reset type
BOOL bInitialState, // initial state
LPCTSTR lpName // object name
);
該函數創建一個Event同步對象,如果CreateEvent調用成功的話,會返回新生成的對象的句柄,否則返回NULL。
參數說明:
lpEventAttributes 一般爲NULL
bManualReset 創建的Event是自動復位還是人工復位.如果true,人工復位, 一旦該Event被設置爲有信號,則它一直會等到ResetEvent()API被調用時纔會恢復 爲無信號. 如果爲false,Event被設置爲有信號,則當有一個wait到它的Thread時, 該Event就會自動復位,變成無信號. 如果想 在每次調用WaitForSingleObject 後讓WINDOWS爲您自動地把事件地狀態恢復爲”無信號”狀態,必須把該參數設爲FALSE,否則,您必須每次調用ResetEvent函數來清除事件
的信號。
bInitialState 初始狀態,true,有信號,false無信號
lpName 事件對象的名稱。您在OpenEvent函數中可能使用。
註釋:
一個Event被創建以後,可以用OpenEvent()API來獲得它的Handle,用CloseHandle() 來關閉它,用SetEvent()或PulseEvent()來設置它使其有信號,用ResetEvent() 來使其無信號,用WaitForSingleObject()或WaitForMultipleObjects()來等待其變爲有信號.
PulseEvent()是一個比較有意思的使用方法,正如這個API的名字,它使一個Event 對象的狀態發生一次脈衝變化,從無信號變成有信號再變成無信號,而整個操作是原子的.
對自動復位的Event對象,它僅釋放第一個等到該事件的thread(如果有),而對於人工復位的Event對象,它釋放所有等待的thread.
這裏有兩個API函數用來修改事件對象的信號狀態:SetEvent和ResetEvent。前者把事件對象設爲”有信號”狀態,而後者正好相反。
在事件對象生成後,必須調用WaitForSingleObject來讓線程進入等待狀態,該函數的語法如下:
WaitForSingleObject proto hObject:DWORD, dwTimeout:DWORD
hObject -->指向同步對象的指針。事件對象其實是同步對象的一種。
dwTimeout --> 等待同步對象變成”有信號”前等待的時間,以毫秒計。當等待的時間超過該值後無信號同步對象仍處於”無信號”狀態,線程不再等待, WaitForSingleObject函數會返回。如果想要線程一直等待,請把該參數設爲INFINITE(該值等於0xffffffff)。