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

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

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

c++中CreateEvent函数解析(1)

發(fā)布時(shí)間:2023/12/18 c/c++ 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++中CreateEvent函数解析(1) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

函數(shù)原型:

?

HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, // SDBOOL bManualReset, // reset typeBOOL bInitialState, // initial stateLPCTSTR lpName // object name );

?

?

lpEventAttributes:指向SECURITY_ATTRIBUTES結(jié)構(gòu)體,此結(jié)構(gòu)體決定函數(shù)的返回句柄是否可以讓子進(jìn)程繼承。如果這個(gè)參數(shù)為NULL,這個(gè)句柄是不能繼承的。一般情況下,這個(gè)參數(shù)設(shè)置為NULL。

bManualReset:指定將創(chuàng)建的EVENT是自動(dòng)復(fù)位還是手動(dòng)復(fù)位。如果為TRUE,需要用ResetEvent(HANDLE)函數(shù)手動(dòng)復(fù)位狀態(tài)為無(wú)信號(hào),即一旦改EVENT被設(shè)置成有信號(hào),則它會(huì)一直等到ResetEvent調(diào)用時(shí)才為無(wú)信號(hào)狀態(tài)。如果為FALSE,當(dāng)一個(gè)有信號(hào)的等待線程被釋放后,系統(tǒng)會(huì)自動(dòng)復(fù)位狀態(tài)為無(wú)信號(hào)狀態(tài)。

bInitialState:指定事件對(duì)象的初始狀態(tài)。如果為TRUE,初始狀態(tài)為有信號(hào),否則為無(wú)信號(hào)。

lpName:? 事件對(duì)象的名稱,以字符串表示。名稱的長(zhǎng)度受MAX_PATH的限制,名稱是大小寫(xiě)敏感的。如果lpName匹配一個(gè)存在的命名的事件對(duì)象,函數(shù)將請(qǐng)求EVENT_ALL_ACCESS來(lái)訪問(wèn)存在的對(duì)象。在這種情況下,bManualReset和bInitialState 被忽略,因?yàn)檫@兩個(gè)參數(shù)已經(jīng)被存在的事件設(shè)置。如果lpEventAttributes參數(shù)不為NULL,這個(gè)參數(shù)可以決定是否句柄被繼承,但是它的安全描述(security-descriptor)成員被忽略。如果lpName 為NULL,創(chuàng)建一個(gè)沒(méi)有名稱的事件。如果lpName 匹配一個(gè)存在的semaphore, mutex, waitable timer, job或者file-mapping對(duì)象的名稱,函數(shù)調(diào)用失敗,GetLastError函數(shù)返回ERROR_INVALID_HANDLE。由于這些對(duì)象共享相同的命名空間,才導(dǎo)致這種情況的發(fā)生。

返回值:??? 函數(shù)返回句柄,該句柄具有EVENT_ALL_ACCESS權(quán)限去訪問(wèn)新的事件對(duì)象,同時(shí)它可以在任何需要事件對(duì)象句柄的函數(shù)中使用。

??? 調(diào)用過(guò)程中的任何線程,都可以在一個(gè)等待函數(shù)中指定事件對(duì)象句柄。當(dāng)指定的對(duì)象的狀態(tài)為有信號(hào)時(shí),單對(duì)象等待函數(shù)(例如WaitForSingleObject)返回。對(duì)于多對(duì)象等待函數(shù)(例如WaitForMultipleObjects),可以指定為任意或所有指定的對(duì)象被置為有信號(hào)狀態(tài)。當(dāng)?shù)却瘮?shù)返回時(shí),等待線程將被釋放去繼續(xù)它的執(zhí)行。?? 事件對(duì)象的初始狀態(tài)由bInitialState參數(shù)指定,用SetEvent函數(shù)可以設(shè)置對(duì)象為有信號(hào)狀態(tài),用ResetEvent函數(shù)可以設(shè)置對(duì)象為無(wú)信號(hào)狀態(tài)。?? 當(dāng)一個(gè)手動(dòng)復(fù)原的事件對(duì)象的狀態(tài)被置為有信號(hào)狀態(tài)時(shí),該對(duì)象將一直保持有信號(hào)狀態(tài),直至明確調(diào)用ResetEvent函數(shù)將其置為無(wú)符號(hào)狀態(tài)。當(dāng)事件對(duì)象被設(shè)置為有信號(hào)狀態(tài)時(shí),任何數(shù)量的等待線程或者隨后等待的線程都會(huì)被釋放。

??? 當(dāng)一個(gè)自動(dòng)復(fù)原事件對(duì)象的狀態(tài)被設(shè)置為有信號(hào)狀態(tài)時(shí),該對(duì)象一直保持有信號(hào)狀態(tài),直至一個(gè)單等待線程被釋放;系統(tǒng)然后會(huì)自動(dòng)重置對(duì)象到無(wú)信號(hào)狀態(tài)。???

多個(gè)進(jìn)程可持有同一個(gè)事件對(duì)象的多個(gè)句柄,可以通過(guò)使用此對(duì)象來(lái)實(shí)現(xiàn)進(jìn)程間的同步。下面的對(duì)象共享機(jī)制是可行的:

  ·在CreateEvent函數(shù)中,lpEventAttributes參數(shù)指定句柄可被繼承時(shí),通過(guò)CreateProcess函數(shù)創(chuàng)建的子進(jìn)程繼承的事件對(duì)象句柄。

  ·一個(gè)進(jìn)程可以在DuplicateHandle函數(shù)中指定事件對(duì)象句柄,從而獲得一個(gè)復(fù)制的句柄,此句柄可以被其它進(jìn)程使用。

? ??? ·一個(gè)進(jìn)程可以在OpenEvent或CreateEvent函數(shù)中指定一個(gè)名字,從而獲得一個(gè)有名的事件對(duì)象句柄。(在調(diào)用OpenEvent或CreateEvent函數(shù)時(shí),一個(gè)進(jìn)程可以指定事件對(duì)象的名字。)

  使用CloseHandle函數(shù)關(guān)閉句柄。當(dāng)進(jìn)程終止時(shí),系統(tǒng)將自動(dòng)關(guān)閉句柄。事件對(duì)象會(huì)被銷毀,當(dāng)最后一個(gè)句柄被關(guān)閉。

?

二、c++CreateEvent函數(shù)在多線程中使用及實(shí)例

?

下面主要演示一下采用CreateEvent實(shí)現(xiàn)多線程。

例子很簡(jiǎn)單,主要測(cè)試CreateEvent中bManualReset:和bInitialState參數(shù)的取值在線程調(diào)用中信號(hào)狀態(tài)的情況。

?

測(cè)試1:

bManualReset:TRUE
bInitialState:TRUE

CreateEvent(NULL, TRUE, TRUE, NULL); //使用手動(dòng)重置為無(wú)信號(hào)狀態(tài),初始化時(shí)有信號(hào)狀態(tài)

example.cpp

#include "iostream" #include "windows.h" using namespace std; DWORD WINAPI ThreadProc1(LPVOID lpParam); DWORD WINAPI ThreadProc2(LPVOID lpParam); HANDLE hEvent = NULL; HANDLE hThread1 = NULL; HANDLE hThread2 = NULL; int main(int argc, char *args[]) { hEvent = CreateEvent(NULL, TRUE, TRUE, NULL)</span>; //使用手動(dòng)重置為無(wú)信號(hào)狀態(tài),初始化時(shí)有信號(hào)狀態(tài) //hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); //當(dāng)一個(gè)等待線程被釋放時(shí),自動(dòng)重置為無(wú)信號(hào)狀態(tài),初始是有信號(hào)狀態(tài) //if (SetEvent(hEvent)) //{ // cout << "setEvent 成功" <<endl; //} hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc1, NULL, 0,NULL); Sleep(200); hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc2, NULL, 0,NULL); Sleep(200); if ( NULL == hThread1) { cout <<"create thread fail!"; } //DWORD dCount = ResumeThread(hThread); //cout << LOWORD(dCount) << endl; return 0; } DWORD WINAPI ThreadProc1(LPVOID lpParam) { cout <<"in thread1@!"<<endl; DWORD dReturn = WaitForSingleObject(hEvent,INFINITE); if ( WAIT_OBJECT_0 == dReturn) { cout <<" thread1 signaled ! "<<endl; } cout <<"in thread1 --signal"<<endl; //SetEvent(hEvent); return 0; } DWORD WINAPI ThreadProc2(LPVOID lpParam) { cout <<"in thread2@!"<<endl; DWORD dReturn = WaitForSingleObject(hEvent,INFINITE); if ( WAIT_OBJECT_0 == dReturn) { cout <<"thread2 signaled ! "<<endl; } cout <<"in thread2--signal"<<endl; return 0; }


執(zhí)行結(jié)果:

?

從結(jié)果中看,執(zhí)行完線程1又執(zhí)行了線程2.

由于hEvent = CreateEvent(NULL, TRUE, TRUE, NULL),使用手動(dòng)重置為無(wú)信號(hào)狀態(tài),初始化時(shí)有信號(hào)狀態(tài)

所以hEvent一直處于有信號(hào)狀態(tài),無(wú)論是線程1釋放后,hEvent仍處于有信號(hào)狀態(tài),所以線程2正常執(zhí)行了。

?

測(cè)試2:

bManualReset:FALSE
bInitialState:TRUE

?

hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); //當(dāng)一個(gè)等待線程被釋放時(shí),自動(dòng)重置為無(wú)信號(hào)狀態(tài),初始是有信號(hào)狀態(tài)


example2.cpp

?

?

#include "iostream" #include "windows.h" using namespace std; DWORD WINAPI ThreadProc1(LPVOID lpParam); DWORD WINAPI ThreadProc2(LPVOID lpParam); HANDLE hEvent = NULL; HANDLE hThread1 = NULL; HANDLE hThread2 = NULL; int main(int argc, char *args[]) { //hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); //使用手動(dòng)重置為無(wú)信號(hào)狀態(tài),初始化時(shí)有信號(hào)狀態(tài) hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); </span>//當(dāng)一個(gè)等待線程被釋放時(shí),自動(dòng)重置為無(wú)信號(hào)狀態(tài),初始是有信號(hào)狀態(tài) //if (SetEvent(hEvent)) //{ // cout << "setEvent 成功" <<endl; //} hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc1, NULL, 0,NULL); Sleep(200); hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc2, NULL, 0,NULL); Sleep(200); if ( NULL == hThread1) { cout <<"create thread fail!"; } //DWORD dCount = ResumeThread(hThread); //cout << LOWORD(dCount) << endl; return 0; } DWORD WINAPI ThreadProc1(LPVOID lpParam) { cout <<"in thread1@!"<<endl; DWORD dReturn = WaitForSingleObject(hEvent,INFINITE); if ( WAIT_OBJECT_0 == dReturn) { cout <<" thread1 signaled ! "<<endl; } cout <<"in thread1 --signal"<<endl; //SetEvent(hEvent); return 0; } DWORD WINAPI ThreadProc2(LPVOID lpParam) { cout <<"in thread2@!"<<endl; DWORD dReturn = WaitForSingleObject(hEvent,INFINITE); if ( WAIT_OBJECT_0 == dReturn) { cout <<"thread2 signaled ! "<<endl; } cout <<"in thread2--signal"<<endl; return 0; }

執(zhí)行結(jié)果:

?

從執(zhí)行結(jié)果中分析,執(zhí)行了線程1,線程2一直在等待,直到主線程結(jié)束。

由于hEvent = CreateEvent(NULL, FALSE, TRUE, NULL),當(dāng)一個(gè)等待線程被釋放時(shí),自動(dòng)重置為無(wú)信號(hào)狀態(tài),初始是有信號(hào)狀態(tài)

初始執(zhí)行線程1的時(shí)候,hEvent是有信號(hào)的,所以線程1正常執(zhí)行;又由于bManualReset=FALSE,所以執(zhí)行完線程1后,hEven

?

WaitForSingleObject(hEvent,INFINITE);


函數(shù)一直在等待hEvent變?yōu)橛行盘?hào)狀態(tài),但是當(dāng)主線程執(zhí)行完,還沒(méi)等待到,線程2程序一直沒(méi)有走下去。

?

?

測(cè)試3:

bManualReset:TRUE
bInitialState:FALSE

hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//使用手動(dòng)重置為無(wú)信號(hào)狀態(tài),初始化時(shí)為無(wú)信號(hào)狀態(tài)

example3.cpp

#include "iostream" #include "windows.h" using namespace std; DWORD WINAPI ThreadProc1(LPVOID lpParam); DWORD WINAPI ThreadProc2(LPVOID lpParam); HANDLE hEvent = NULL; HANDLE hThread1 = NULL; HANDLE hThread2 = NULL; int main(int argc, char *args[]) { //hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); //使用手動(dòng)重置為無(wú)信號(hào)狀態(tài),初始化時(shí)有信號(hào)狀態(tài) //hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); //當(dāng)一個(gè)等待線程被釋放時(shí),自動(dòng)重置為無(wú)信號(hào)狀態(tài),初始是有信號(hào)狀態(tài) hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//使用手動(dòng)重置為無(wú)信號(hào)狀態(tài),初始化時(shí)為無(wú)信號(hào)狀態(tài)</span> //if (SetEvent(hEvent)) //{ // cout << "setEvent 成功" <<endl; //} hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc1, NULL, 0,NULL); Sleep(200); hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc2, NULL, 0,NULL); Sleep(200); if ( NULL == hThread1) { cout <<"create thread fail!"; } //DWORD dCount = ResumeThread(hThread); //cout << LOWORD(dCount) << endl; return 0; } DWORD WINAPI ThreadProc1(LPVOID lpParam) { cout <<"in thread1@!"<<endl; DWORD dReturn = WaitForSingleObject(hEvent,INFINITE); if ( WAIT_OBJECT_0 == dReturn) { cout <<" thread1 signaled ! "<<endl; } cout <<"in thread1 --signal"<<endl; //SetEvent(hEvent); return 0; } DWORD WINAPI ThreadProc2(LPVOID lpParam) { cout <<"in thread2@!"<<endl; DWORD dReturn = WaitForSingleObject(hEvent,INFINITE); if ( WAIT_OBJECT_0 == dReturn) { cout <<"thread2 signaled ! "<<endl; } cout <<"in thread2--signal"<<endl; return 0; }

執(zhí)行結(jié)果,可想而知,只能輸出:
in?thread1@!?
in?thread2@!?
因?yàn)槌跏紴闊o(wú)信號(hào)狀態(tài),所以hEvent一直處于無(wú)信號(hào)狀態(tài),因此這兩個(gè)線程一直在等待,直到主線程結(jié)束。

?

修改:放開(kāi)例子中的注釋部分:

if (SetEvent(hEvent))//設(shè)置信號(hào)為有信號(hào)狀態(tài)
{
cout << "setEvent 成功" <<endl;
}

執(zhí)行結(jié)果:

?

可見(jiàn),線程1和線程2都執(zhí)行了。

因?yàn)檎{(diào)用SetEvent,事件變?yōu)橛行盘?hào)狀態(tài),線程1執(zhí)行;又由于線程1釋放后,hEvent仍舊處于有信號(hào)狀態(tài),所以線程2也執(zhí)行了。

?

再修改:在線程1中,添加ResetEvent(hEvent)(手動(dòng)設(shè)置事件為無(wú)信號(hào)狀態(tài)),則線程2不會(huì)執(zhí)行。

?

測(cè)試4:

bManualReset:FALSE
bInitialState:FALSE

hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);//線程釋放后自動(dòng)重置為無(wú)信號(hào)狀態(tài),初始化時(shí)為無(wú)信號(hào)狀態(tài)

example4.cpp

?

#include "iostream" #include "windows.h" using namespace std; DWORD WINAPI ThreadProc1(LPVOID lpParam); DWORD WINAPI ThreadProc2(LPVOID lpParam); HANDLE hEvent = NULL; HANDLE hThread1 = NULL; HANDLE hThread2 = NULL; int main(int argc, char *args[]) { //hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); //使用手動(dòng)重置為無(wú)信號(hào)狀態(tài),初始化時(shí)有信號(hào)狀態(tài) //hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); //當(dāng)一個(gè)等待線程被釋放時(shí),自動(dòng)重置為無(wú)信號(hào)狀態(tài),初始是有信號(hào)狀態(tài) //hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//使用手動(dòng)重置為無(wú)信號(hào)狀態(tài),初始化時(shí)為無(wú)信號(hào)狀態(tài) hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);//使用手動(dòng)重置為無(wú)信號(hào)狀態(tài),初始化時(shí)為無(wú)信號(hào)狀態(tài) if (SetEvent(hEvent)) { cout << "setEvent 成功" <<endl; } hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc1, NULL, 0,NULL); Sleep(200); hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc2, NULL, 0,NULL); Sleep(200); if ( NULL == hThread1) { cout <<"create thread fail!"; } //DWORD dCount = ResumeThread(hThread); //cout << LOWORD(dCount) << endl; return 0; } DWORD WINAPI ThreadProc1(LPVOID lpParam) { cout <<"in thread1@!"<<endl; DWORD dReturn = WaitForSingleObject(hEvent,INFINITE); if ( WAIT_OBJECT_0 == dReturn) { cout <<" thread1 signaled ! "<<endl; } cout <<"in thread1 --signal"<<endl; //SetEvent(hEvent); return 0; } DWORD WINAPI ThreadProc2(LPVOID lpParam) { cout <<"in thread2@!"<<endl; DWORD dReturn = WaitForSingleObject(hEvent,INFINITE); if ( WAIT_OBJECT_0 == dReturn) { cout <<"thread2 signaled ! "<<endl; } cout <<"in thread2--signal"<<endl; return 0; }

?

?

?

由于調(diào)用SetEvent,hEvent為有信號(hào)狀態(tài),線程1正常執(zhí)行,又由于調(diào)用完線程1后,hEvent自動(dòng)重置為無(wú)信號(hào)狀態(tài),所以線程2只能在等待,直到主線程退出。

修改:線程1中的SetEvent(hEvent);的注釋去掉,再運(yùn)行,則線程1和線程2 都會(huì)執(zhí)行。

總結(jié)

以上是生活随笔為你收集整理的c++中CreateEvent函数解析(1)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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