CreateEvent的使用方法收藏
新一篇: PreCreateWindow的作用和用法 | 舊一篇: VC中_T()的作用
事件對象就像一個開關:它僅僅有兩種狀態---開和關。當一個事件處於”開”狀態,我們稱其為”有信號”否則稱為”無信號”。能夠在一個線程的運行函數中創建一個事件對象,然后觀察它的狀態,假設是”無信號”就讓該線程睡眠,這樣該線程占用的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)。
發表於 @ 2008年04月18日 13:30:00|評論(0)|編輯
新一篇: PreCreateWindow的作用和用法 | 舊一篇: VC中_T()的作用
Visual C++中的多線程收藏
新一篇: 特洛伊木馬(一) | 舊一篇: 用戶接口與作業調度
以前,以前研究過了java中的多線程問題,特別是加鎖和同步問題,可是,在C++中,確沒有這么簡單了。因為C沒有提供像java里的線程類,一些同步的實現必須靠自己程序實現,稍顯復雜。一般來說,在C++里面創建和終止線程的函數為:_beginthread和_endthread兩個函數,當然,也能夠用CreateThread和ExitThread。詳細的使用方式能夠查看msdn。
那么,怎么樣實現加鎖與同步呢?能夠使用createMutex函數以及createEvent方法等來實現,詳細能夠參考下例:














































































發表於 @ 2006年10月29日 19:54:00|評論(2)|編輯
新一篇: 特洛伊木馬(一) | 舊一篇: 用戶接口與作業調度
Windows API一日一練(45)CreateEvent和SetEvent函數收藏
新一篇: Windows API一日一練(46)EnterCriticalSection和LeaveCriticalSection函數 | 舊一篇: Windows API一日一練(44)wsprintf函數
發表於 @ 2007年09月25日 21:32:00|評論(0)|編輯
新一篇: Windows API一日一練(46)EnterCriticalSection和LeaveCriticalSection函數 | 舊一篇: Windows API一日一練(44)wsprintf函數
Win32 API 經常使用函數之二收藏
新一篇: Win32 API 經常使用函數之三——注冊表操作(上) | 舊一篇: Win32 API 經常使用函數之中的一個
【事件】事件用處多是控制線程間的同步。
最典型的應用就是CreateThread之后等待線程函數的啟動。如Main線程里CreateThread,它之后的操作依賴於子線程,那么它通常會 在CreateThread之后推斷HANDLE是否有效,然后進入等待。(當然在這之前,一個Event是已經創建好的,並初始化為未通知狀態)子線程 啟動后完畢了初始化操作,並設置Event為已通知狀態。這時,一直在等待該事件的Main線程發現該事件已經得到通知,因此它就變成可調度線程。這時 Main線程知道子線程已經完畢了初始化操作。
CreateEvent函數用於創建一個Event,其原型例如以下:






- 第一個參數同CreateThread相似,也是安全級別相關,通常被被設置為NULL,以獲得默認的安全級別。
- 第二個參數是個布爾值,它可以告訴系統是創建一個人工重置的事件(TRUE)還是創建一個自己主動重置的事件( FALSE)。
- 第三個參數也是布爾值,用於指明該事件是要初始化為已通知狀態(TRUE)還是未通知狀態(FALSE)。
- 第四個參數是一個字符串,用於標示這個事件的名字。
- 已通知狀態和未通知狀態
事件僅僅有兩種狀態,已通知表示這個事件已經被設置過了(能夠理解為發生了),未通知表示還沒有發生。一般設置為未通知狀態,並由SetEvent設置為已 通知狀態。當然也能夠反着做,CreateEvent時設置為已通知狀態,然后由ResetEvent設置為未通知狀態。 - 人工重置與自己主動重置
自己主動重置的事件定義了應該成功等待的副作用規則,即當線程成功地等待到該對象時,自己主動重置的事件就會自己主動重置到未通知狀態。
人工重置則須要調用ResetEvent函數設置為未通知狀態。 - 名字共享
這個參數非常重要,Win32 API中有非常多方法有這個參數,它遵從一種按名字共享的規則。
假設傳入一個非NULL字符串(最多260個字符),那么在全局空間,共享該HANDLE,這個全局可以是跨進程的名字空間,即在還有一個進程中依舊可以使用該名字的HANDLE。
假設希望避免這樣的全局范圍內的共享,那么應該傳入NULL,以一種匿名的方式創建Event等,這樣,它僅僅在當前線程內可見。
應用程序可以確定它是否確實創建了一個新內核對象,而不是打開了一個現有的對象。方法是在調用C r e a t e *函數后馬上調用G e t L a s t E r r o r:假設為ERROR_ALREADY_EXISTS,那么表示系統內已經存在了這樣名字的對象。
Open*是去查看名字空間中是否有這個名字的內核對象存在調用C r e a t e *函數與調用O p e n *函數之間的主要區別是,假設對象並不存在,那么C r e a t e *函數將創建該對象,而O p e n *函數則執行失敗。
PulseEvent函數使得事件變為已通知狀態,然后馬上又變為未通知狀態,這就像在調用SetEvent后又馬上調用ResetEvent函數一樣。 假設在人工重置的事件上調用PulseEvent函數,那么在發出該事件時,等待該事件的不論什么一個線程或全部線程將變為可調度線程。假設在自己主動重置事件上 調用P u l s e E v e n t函數,那么僅僅有一個等待該事件的線程變為可調度線程。假設在發出事件時沒有不論什么線程在等待該事件,那么將不起不論什么作用。
【等待函數】
等待函數用來監聽事件的已通知狀態。WaitForSingleObject和WaitForMultipleObjects兩個函數分別用以等待單個事件和多個事件。










dwMilliseconds 參數表明等待的時間,假設在這個時間段中事件為已通知狀態,那么對於Single版本號將返回WAIT_OBJECT_0,對於Multiple版本號將返回 WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount– 1)。假設沒有等到將返回WAIT_TIMEOUT。
Multiple版本號中的bWaitAll表示想要讓它使用何種方式等待。假設為該參數傳遞TRUE,那么在全部對象變為已通知狀態之前,該函數將不同意調用線程執行。通常是FALSE,即僅僅要有一個事件被對應,則線程可調度。
發表於 @ 2007年10月28日 18:04:00|評論(0)|編輯