日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

事件EVENT与waitforsingleobject的使用以及Mutex与Event的区别

發(fā)布時(shí)間:2025/3/17 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 事件EVENT与waitforsingleobject的使用以及Mutex与Event的区别 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Mutex與Event控制互斥事件的使用詳解最近寫(xiě)一程序,誤用了Mutex的功能,錯(cuò)把Mutex當(dāng)Event用了。【Mutex】使用Mutex的主要函數(shù):CreateMutex、ReleaseMutex、OpenMutex、WaitForSingleObject、WaitForMultipleObjects。CreateMutex:其中第二個(gè)參數(shù)是表示當(dāng)前線程擁有權(quán)。TRUE:創(chuàng)建線程獲得初始所有權(quán)的互斥對(duì)象(即信號(hào)已被當(dāng)前線程獲得,沒(méi)有釋放前其它線程不能獲得。如果當(dāng)前線程調(diào)用了WaitForSingleObject 函 數(shù), 則釋放次數(shù)等于調(diào)用次數(shù)加1)。     FALSE:創(chuàng)建線程沒(méi)有獲得互斥對(duì)象的所有權(quán)。也就是自由爭(zhēng)取,看誰(shuí)先Wait到。 不管怎么樣,MUtex的釋放規(guī)則是:誰(shuí)擁有誰(shuí)釋放,還有在線程結(jié)束時(shí), 線程所獲得的Mutex自動(dòng)釋放;當(dāng)然還可以使用命名Mutex做唯一性驗(yàn)證,這個(gè)在整個(gè)windows生存期下有效。【Event】與Mutex不一樣,Event是任何時(shí)候都是可以操作的,而且沒(méi)有同調(diào)用多次WaitForSingleObject和同時(shí)釋放多次一說(shuō)。它的主要操作函數(shù)有: CreateEvent、SetEvent、WaitForSingleObject。CreateEvent參數(shù)說(shuō)明。第二個(gè)參數(shù)表示調(diào)用WaitForSingleObject后手動(dòng)(TRUE)/自動(dòng)(FALSE)為無(wú)信號(hào)狀態(tài)。第三個(gè)參數(shù)表示初始狀態(tài)為有(TRUE)/無(wú)(FALSE)信號(hào)。  Event的獲得是通過(guò)一個(gè)隊(duì)列去排隊(duì)獲得的,SetEvent沒(méi)有限制使用,在任何可以調(diào)用的地方都可以調(diào)用。Mutex,的互斥是以線程為基本單位,而Event是以代碼段為基本單位。所以在兩者的使用上有著不同的功能用途。https://www.cnblogs.com/upendi/archive/2013/02/25/2932154.html

?

?

事件EVENT與waitforsingleobject的使用 事件event與waitforsingleobject的配合使用,能夠解決很多同步問(wèn)題,也可以在數(shù)據(jù)達(dá)到某個(gè)狀態(tài)時(shí)啟動(dòng)另一個(gè)線程的執(zhí)行,如報(bào)警。event的幾個(gè)函數(shù):1、CreateEvent和OpenEventHANDLE WINAPI CreateEvent(__in LPSECURITY_ATTRIBUTES lpEventAttributes, //表示安全控制,一般直接傳入NULL,表示不能被子進(jìn)程繼承__in BOOL bManualReset, //參數(shù)確定事件是手動(dòng)置位還是自動(dòng)置位,傳入TRUE表示手動(dòng)置位,傳入FALSE表示自動(dòng)置位。__in BOOL bInitialState, //Event的初始狀態(tài), TRUE為觸發(fā),FALSE未觸發(fā)__in LPCTSTR lpName //Event object的名字,NULL表示沒(méi)名字(without a name));要是CreateEvent創(chuàng)建的事件沒(méi)名字 這個(gè)函數(shù)就沒(méi)啥用了,不多做介紹,可查看msn。 1 HANDLE WINAPI OpenEvent( //獲得已經(jīng)存在的Event的事件句柄 2 __in DWORD dwDesiredAccess, 3 __in BOOL bInheritHandle, 4 __in LPCTSTR lpName //要打開(kāi)的事件名字 5 );2、SetEvent,觸發(fā)事件BOOL SetEvent(HANDLE hEvent);3、ResetEvent,使事件狀態(tài)設(shè)為未觸發(fā),如在創(chuàng)建事件時(shí)第二個(gè)參數(shù)為T(mén)RUE手動(dòng)設(shè)置,則需要該函數(shù)去恢復(fù)事件為未觸發(fā)狀態(tài)。BOOL SetEvent(HANDLE hEvent);4、PulseEvent, 如在創(chuàng)建事件時(shí)第二個(gè)參數(shù)為T(mén)RUE手動(dòng)設(shè)置,其功能相當(dāng)于SetEvent()后立即調(diào)用ResetEvent()BOOL PulseEvent(HANDLE hEvent)也就是說(shuō)在自動(dòng)重置模式下PulseEvent和SetEvent的作用沒(méi)有什么區(qū)別,但在手動(dòng)模式下PulseEvent就有明顯的不同, 可以比較容易的控制程序是單步走,還是連續(xù)走。如果讓循環(huán)按要求執(zhí)行一次就用PulseEvent,如果想讓循環(huán)連續(xù)不停的運(yùn)轉(zhuǎn)就用SetEvent ,在要求停止的地方發(fā)個(gè)ResetEvent就OK了。5、CloseHandle(),關(guān)閉該句柄。**********WaitForSingleObject函數(shù)。使線程處于等待狀態(tài),如等待某一事件的觸發(fā)。DWORD WINAPI WaitForSingleObject(HANDLE hHandle, //等待的觸發(fā)句柄 , 如前面說(shuō)的Event的句柄DWORD dwMilliseconds //等待多長(zhǎng)時(shí)間,單位ms 如5000 則為5s 若為INFINITE表示無(wú)限等待 );

?http://www.cnblogs.com/LouMengzhao/p/6076368.html

http://blog.sina.com.cn/s/blog_6163bdeb0100qlw1.html

?

事件和其他量一樣,也是一個(gè)內(nèi)核對(duì)象。使用事件可以進(jìn)行同步,主要是可以規(guī)定先后順序。事件分為手動(dòng)置位事件和自動(dòng)置位事件,兩個(gè)的關(guān)系是什么呢?手動(dòng)置位事件就是你一旦觸發(fā)之后,所有的狀態(tài)都被釋放。自動(dòng)置位事件你觸發(fā)之后,只有一個(gè)狀態(tài)被釋放,這個(gè)時(shí)候就有不確定性了。如何使用事件?有這么幾個(gè)函數(shù)。第一個(gè) CreateEvent函數(shù)功能:創(chuàng)建事件函數(shù)原型:HANDLECreateEvent(LPSECURITY_ATTRIBUTESlpEventAttributes,BOOLbManualReset,BOOLbInitialState,LPCTSTRlpName);函數(shù)說(shuō)明:第一個(gè)參數(shù)表示安全控制,一般直接傳入NULL。第二個(gè)參數(shù)確定事件是手動(dòng)置位還是自動(dòng)置位,傳入TRUE表示手動(dòng)置位,傳入FALSE表示自動(dòng)置位。如果為自動(dòng)置位,
則對(duì)該事件調(diào)用WaitForSingleObject()后會(huì)自動(dòng)調(diào)用ResetEvent()使事件變成未觸發(fā)狀態(tài)。打個(gè)小小比方,
手動(dòng)置位事件相當(dāng)于教室門(mén),教室門(mén)一旦打開(kāi)(被觸發(fā)),所以有人都可以進(jìn)入直到老師去關(guān)上教室門(mén)(事件變成未觸發(fā))。
自動(dòng)置位事件就相當(dāng)于醫(yī)院里拍X光的房間門(mén),門(mén)打開(kāi)后只能進(jìn)入一個(gè)人,這個(gè)人進(jìn)去后會(huì)將門(mén)關(guān)上,其它人不能進(jìn)入除非門(mén)重新被打開(kāi)(事件重新被觸發(fā))。第三個(gè)參數(shù)表示事件的初始狀態(tài),傳入TRUR表示已觸發(fā)。第四個(gè)參數(shù)表示事件的名稱(chēng),傳入NULL表示匿名事件。第二個(gè) OpenEvent函數(shù)功能:根據(jù)名稱(chēng)獲得一個(gè)事件句柄。函數(shù)原型:HANDLEOpenEvent(DWORDdwDesiredAccess,BOOLbInheritHandle,LPCTSTRlpName //名稱(chēng));函數(shù)說(shuō)明:第一個(gè)參數(shù)表示訪問(wèn)權(quán)限,對(duì)事件一般傳入EVENT_ALL_ACCESS。詳細(xì)解釋可以查看MSDN文檔。第二個(gè)參數(shù)表示事件句柄繼承性,一般傳入TRUE即可。第三個(gè)參數(shù)表示名稱(chēng),不同進(jìn)程中的各線程可以通過(guò)名稱(chēng)來(lái)確保它們?cè)L問(wèn)同一個(gè)事件。第三個(gè)SetEvent函數(shù)功能:觸發(fā)事件函數(shù)原型:BOOLSetEvent(HANDLEhEvent);函數(shù)說(shuō)明:每次觸發(fā)后,必有一個(gè)或多個(gè)處于等待狀態(tài)下的線程變成可調(diào)度狀態(tài)。第四個(gè)ResetEvent函數(shù)功能:將事件設(shè)為末觸發(fā)函數(shù)原型:BOOLResetEvent(HANDLEhEvent);最后一個(gè)事件的清理與銷(xiāo)毀由于事件是內(nèi)核對(duì)象,因此使用CloseHandle()就可以完成清理與銷(xiāo)毀了。關(guān)于之前的那個(gè)問(wèn)題,如何來(lái)設(shè)置同步呢?首先是初始化:? ?//事件與關(guān)鍵段 ?HANDLE g_hThreadEvent; ?CRITICAL_SECTION g_csThreadCode; ? ? //初始化事件和關(guān)鍵段 自動(dòng)置位,初始無(wú)觸發(fā)的匿名事件 ? g_hThreadEvent = CreateEvent(NULL, FALSE, FALSE, NULL); ? InitializeCriticalSection(&g_csThreadCode); ? //銷(xiāo)毀事件和關(guān)鍵段 ? CloseHandle(g_hThreadEvent); ? DeleteCriticalSection(&g_csThreadCode); ?? ? ?關(guān)鍵代碼段修改: ?主循環(huán)當(dāng)中: ? while (i < THREAD_NUM) ? { ? handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL); ? WaitForSingleObject(g_hThreadEvent, INFINITE); //等待事件被觸發(fā)i++; ? } ?線程函數(shù)當(dāng)中: ?? ?int nThreadNum = *(int *)pPM; ? SetEvent(g_hThreadEvent); //觸發(fā)事件于是就可完成同步工作。匿名和有名的差別:匿名的時(shí)候具有親緣關(guān)系的才能看到,而有名管道則可以在其他進(jìn)程當(dāng)中看到,這個(gè)是大部分的差別。如果是有名的,那么create的時(shí)候,如果有名的已經(jīng)存在,則返回之前的相應(yīng)的句柄。?另外需要注意的就是注意等待的副作用,如果是自動(dòng)重置,可能wait觸發(fā)之后會(huì)reset.關(guān)于函數(shù)pulseEvent函數(shù)功能:將事件觸發(fā)后立即將事件設(shè)置為未觸發(fā),相當(dāng)于觸發(fā)一個(gè)事件脈沖。函數(shù)原型:BOOLPulseEvent(HANDLEhEvent);函數(shù)說(shuō)明:這是一個(gè)不常用的事件函數(shù),此函數(shù)相當(dāng)于SetEvent()后立即調(diào)用ResetEvent();此時(shí)情況可以分為兩種:1.對(duì)于手動(dòng)置位事件,所有正處于等待狀態(tài)下線程都變成可調(diào)度狀態(tài)。2.對(duì)于自動(dòng)置位事件,所有正處于等待狀態(tài)下線程只有一個(gè)變成可調(diào)度狀態(tài)。此后事件是末觸發(fā)的。該函數(shù)不穩(wěn)定,因?yàn)闊o(wú)法預(yù)知在調(diào)用PulseEvent ()時(shí)哪些線程正處于等待狀態(tài)。?如何理解,可以理解為一個(gè)脈沖,只解放當(dāng)時(shí)在等待的那些,而之后的就不在考慮了。一個(gè)簡(jiǎn)答的例子解釋:觸發(fā)一個(gè)事件脈沖PulseEvent ()寫(xiě)一個(gè)例子,主線程啟動(dòng)7個(gè)子線程,其中有5個(gè)線程Sleep(10)后對(duì)一事件調(diào)用等待函數(shù)(稱(chēng)為快線程),
另有2個(gè)線程Sleep(100)后也對(duì)該事件調(diào)用等待函數(shù)(稱(chēng)為慢線程)。主線程啟動(dòng)所有子線程后再Sleep(50)保證有5個(gè)快線程都正處于等待狀態(tài)中。
此時(shí)若主線程觸發(fā)一個(gè)事件脈沖,那么對(duì)于手動(dòng)置位事件,這5個(gè)線程都將順利執(zhí)行下去。對(duì)于自動(dòng)置位事件,這5個(gè)線程中會(huì)有中一個(gè)順利執(zhí)行下去。
而不論手動(dòng)置位事件還是自動(dòng)置位事件,那2個(gè)慢線程由于Sleep(100)所以會(huì)錯(cuò)過(guò)事件脈沖,因此慢線程都會(huì)進(jìn)入等待狀態(tài)而無(wú)法順利執(zhí)行下去。? http://blog.sina.com.cn/s/blog_c33b15000102x3oa.html

總結(jié)

以上是生活随笔為你收集整理的事件EVENT与waitforsingleobject的使用以及Mutex与Event的区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。