1. 程式人生 > >Event原理解析

Event原理解析

Event原理解析

多執行緒同步Event,主要用於執行緒間的等待通知。

核心物件中,事件核心物件是個最基本的物件。它們包含一個使用計數(與所有核心物件一樣),一個用於指明該事件是個自動重置的事件還是一個人工重置的事件的布林值,另一個用於指明該事件處於已通知狀態還是未通知狀態的布林值。

 事件能夠通知一個操作已經完成。有兩種不同型別的事件物件。一種是人工重置的事件,另一種是自動重置的事件。當人工重置的事件得到通知時,等待該事件的所有執行緒均變為可排程執行緒。當一個自動重置的事件得到通知時,等待該事件的執行緒中只有一個執行緒變為可排程執行緒。

 當一個執行緒執行初始化操作,然後通知另一個執行緒執行剩餘的操作時,事件使用得最多。事件初始化為未通知狀態,然後,當該執行緒完成它的初始化操作後,它就將事件設定為已通知狀態。這時,一直在等待該事件的另一個執行緒發現該事件已經得到通知,因此它就變成可排程執行緒。


Event API

Event function Description
CreateEvent Creates or opens a named or unnamed event object.
CreateEventEx Creates or opens a named or unnamed event object and returns a handle to the object.
OpenEvent Opens an existing named event object.
PulseEvent Sets the specified event object to the signaled state and then resets it to the nonsignaled state after releasing the appropriate number of waiting threads.
ResetEvent Sets the specified event object to the nonsignaled state.
SetEvent Sets the specified event object to the signaled state.

OK上面是Event的基本函式(也可以直接點選進去CSDN看引數什麼的下面是我的部分翻譯),那麼下面我面就來細細的接觸接觸吧。

Event函式解析

HANDLECreateEvent(

LPSECURITY_ATTRIBUTESlpEventAttributes,// 安全屬性

BOOLbManualReset,// 復位方式

BOOLbInitialState,// 初始狀態

LPCTSTRlpName // 物件名稱

);

引數

lpEventAttributes[輸入] 一個指向SECURITY_ATTRIBUTES結構的指標,確定返回的控制代碼是否可被子程序繼承。如果lpEventAttributes是NULL,此控制代碼不能被繼承。 Windows NT/2000:lpEventAttributes的結構中的成員為新的事件指定了一個安全符。如果lpEventAttributes是NULL,事件將獲得一個預設的安全符。bManualReset[輸入] 指定將事件物件建立成手動復原還是自動復原。如果是TRUE,那麼必須用ResetEvent函式來手工將事件的狀態復原到無訊號狀態。如果設定為FALSE,當事件被一個等待執行緒釋放以後,系統將會自動將事件狀態復原為無訊號狀態。bInitialState[輸入] 指定事件物件的初始狀態。如果為TRUE,初始狀態為有訊號狀態;否則為無訊號狀態。 lpName[輸入] 指定事件的物件的名稱,是一個以0結束的字串指標。名稱的字元格式限定在MAX_PATH之內。名字是對大小寫敏感的。 如果lpName指定的名字,與一個存在的命名的事件物件的名稱相同,函式將請求EVENT_ALL_ACCESS來訪問存在的物件。這時候,由於bManualReset和bInitialState引數已經在建立事件的程序中設定,這兩個引數將被忽略。如果lpEventAttributes是引數不是NULL,它將確定此控制代碼是否可以被繼承,但是其安全描述符成員將被忽略。 如果lpName為NULL,將建立一個無名的事件物件。 如果lpName的和一個存在的訊號、互斥、等待計時器、作業或者是檔案對映物件名稱相同,函式將會失敗,在GetLastError函式中將返回ERROR_INVALID_HANDLE。造成這種現象的原因是這些物件共享同一個名稱空間。

一個Event被建立以後,可以用OpenEvent()API來獲得它的Handle,用CloseHandle() 來關閉它,用SetEvent()或PulseEvent()來設定它使其有訊號,用ResetEvent() 來使其無訊號,用WaitForSingleObject()或WaitForMultipleObjects()來等待 其變為有訊號.

PulseEvent()是一個比較有意思的使用方法,正如這個API的名字,它使一個Event 物件的狀態發生一次脈衝變化,從無訊號變成有訊號再變成無訊號,而整個操作是原子的. 對自動復位的Event物件,它僅釋放第一個等到該事件的thread(如果有),而對於 人工復位的Event物件,它釋放所有等待的thread.

OpenEvent

HANDLEOpenEvent(   DWORD  dwDesiredAccess ,   BOOL  bInheritHandle ,   LPCTSTR  lpName   );   引數說明   dwDesiredAccess  【in】指定對事件物件的請求訪問許可權,如果安全描述符指定的物件不允許要求通過對呼叫該函式的過程,函式將返回失敗。 該引數必須設定為以下值: EVENT_ALL_ACCESS 指定事件物件所有可能的許可權  bInheritHandle  【in】指定是否返回的控制代碼是否繼承 。該引數必須設定為false  lpName  【in】指向一個以null結束的字串,即將要開啟的事件物件的名字。名稱是區分大小寫的。

Event 原理就先說那麼多吧,上面沒有提及的函式,在我前面的文章都有詳細的說明和解析!

也可參照秒殺多執行緒第六篇 經典執行緒同步 事件Event。

最後總結下事件Event(morewindows

1.事件是核心物件,事件分為手動置位事件自動置位事件。事件Event內部它包含一個使用計數(所有核心物件都有),一個布林值表示是手動置位事件還是自動置位事件,另一個布林值用來表示事件有無觸發。

2.事件可以由SetEvent()來觸發,由ResetEvent()來設成未觸發。還可以由PulseEvent()來發出一個事件脈衝。

3.事件可以解決執行緒間同步問題,因此也能解決互斥問題。