? CreateEvent的使用方法 收藏
新一篇:?PreCreateWindow的作用和用法 ?|? 舊一篇:?VC中_T()的作用
事件對象就像一個開關(guān):它僅僅有兩種狀態(tài)---開和關(guān)。當(dāng)一個事件處于”開”狀態(tài),我們稱其為”有信號”否則稱為”無信號”。能夠在一個線程的運行函數(shù)中創(chuàng)建一個事件對象,然后觀察它的狀態(tài),假設(shè)是”無信號”就讓該線程睡眠,這樣該線程占用的CPU時間就比較少。
產(chǎn)生事件對象的函數(shù)例如以下:??
HANDLE? ???CreateEvent(
??????? LPSECURITY_ATTRIBUTES? ???lpEventAttributes,? ???//? ???SD? ?
? ?? ???BOOL? ???bManualReset,? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? //? ???reset? ???type? ?
? ?? ???BOOL? ???bInitialState,? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??????? ? //? ???initial? ???state? ?
? ?? ???LPCTSTR? ???lpName???????????????????????????????????????????????????????//? ???object? ???name? ?
? ? );? ?
? ? 該函數(shù)創(chuàng)建一個Event同步對象,假設(shè)CreateEvent調(diào)用成功的話,會返回新生成的對象的句柄,否則返回NULL。
參數(shù)說明:
??? lpEventAttributes? ???一般為NULL???
??? bManualReset? ?? ?? ?? ?? ?創(chuàng)建的Event是自己主動復(fù)位還是人工復(fù)位.假設(shè)true,人工復(fù)位,?? 一旦該Event被設(shè)置為有信號,則它一直會等到ResetEvent()API被調(diào)用時才會恢復(fù) 為無信號.? ???假設(shè)為false,Event被設(shè)置為有信號,則當(dāng)有一個wait到它的Thread時,??該Event就會自己主動復(fù)位,變成無信號.???假設(shè)想 在每次調(diào)用WaitForSingleObject 后讓W(xué)INDOWS為您自己主動地把事件地狀態(tài)恢復(fù)為”無信號”狀態(tài),必須把該參數(shù)設(shè)為FALSE,否則,您必須每次調(diào)用ResetEvent函數(shù)來清除事件 的信號。
??? bInitialState? ?? ?? ?? ? 初始狀態(tài),true,有信號,false無信號? ?
? ? lpName??????????????????事件對象的名稱。您在OpenEvent函數(shù)中可能使用。
凝視:
??? 一個Event被創(chuàng)建以后,能夠用OpenEvent()API來獲得它的Handle,用CloseHandle()??? 來關(guān)閉它,用SetEvent()或PulseEvent()來設(shè)置它使其有信號,用ResetEvent()?????? 來使其無信號,用WaitForSingleObject()或WaitForMultipleObjects()來等待其變?yōu)橛行盘?? ?
? ?
? ? PulseEvent()是一個比較有意思的用法,正如這個API的名字,它使一個Event?對象的狀態(tài)發(fā)生一次脈沖變化,從無信號變成有信號再變成無信號,而整個操作是原子的.? ?
? ? 對自己主動復(fù)位的Event對象,它僅釋放第一個等到該事件的thread(假設(shè)有),而對于人工復(fù)位的Event對象,它釋放全部等待的thread.??
?
?
這里有兩個API函數(shù)用來改動事件對象的信號狀態(tài):SetEvent和ResetEvent。前者把事件對象設(shè)為”有信號”狀態(tài),而后者正好相反。
在事件對象生成后,必須調(diào)用WaitForSingleObject來讓線程進入等待狀態(tài),該函數(shù)的語法例如以下:??
WaitForSingleObject proto hObject:DWORD, dwTimeout:DWORD??
hObject -->指向同步對象的指針。事件對象事實上是同步對象的一種。
dwTimeout --> 等待同步對象變成”有信號”前等待的時間,以毫秒計。當(dāng)?shù)却臅r間超過該值后無信號同步對象仍處于”無信號”狀態(tài),線程不再等待, WaitForSingleObject函數(shù)會返回。假設(shè)想要線程一直等待,請把該參數(shù)設(shè)為INFINITE(該值等于0xffffffff)。??
發(fā)表于 @ 2008年04月18日 13:30:00 | 評論( 0 ) | 編輯
新一篇:?PreCreateWindow的作用和用法 ?|? 舊一篇:?VC中_T()的作用
? Visual C++中的多線程 收藏
新一篇:?特洛伊木馬(一) ?|? 舊一篇:?用戶接口與作業(yè)調(diào)度
以前,以前研究過了java中的多線程問題,特別是加鎖和同步問題,可是,在C++中,確沒有這么簡單了。因為C沒有提供像java里的線程類,一些同步的實現(xiàn)必須靠自己程序?qū)崿F(xiàn),稍顯復(fù)雜。一般來說,在C++里面創(chuàng)建和終止線程的函數(shù)為:_beginthread和_endthread兩個函數(shù),當(dāng)然,也能夠用CreateThread和ExitThread。詳細的使用方式能夠查看msdn。
那么,怎么樣實現(xiàn)加鎖與同步呢?能夠使用createMutex函數(shù)以及createEvent方法等來實現(xiàn),詳細能夠參考下例:














































































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






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










??? ?? dwMilliseconds 參數(shù)表明等待的時間,假設(shè)在這個時間段中事件為已通知狀態(tài),那么對于Single版本號將返回WAIT_OBJECT_0,對于Multiple版本號將返回 WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount– 1)。假設(shè)沒有等到將返回WAIT_TIMEOUT。
??? ?? Multiple版本號中的bWaitAll表示想要讓它使用何種方式等待。假設(shè)為該參數(shù)傳遞TRUE,那么在全部對象變?yōu)橐淹ㄖ獱顟B(tài)之前,該函數(shù)將不同意調(diào)用線程執(zhí)行。通常是FALSE,即僅僅要有一個事件被對應(yīng),則線程可調(diào)度。
??? ??
發(fā)表于 @ 2007年10月28日 18:04:00 | 評論( 0 ) | 編輯
新一篇:?Win32 API 經(jīng)常使用函數(shù)之三——注冊表操作(上) ?|? 舊一篇:?Win32 API 經(jīng)常使用函數(shù)之中的一個
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
