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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

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

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

函數原型:

?

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

?

?

lpEventAttributes:指向SECURITY_ATTRIBUTES結構體,此結構體決定函數的返回句柄是否可以讓子進程繼承。如果這個參數為NULL,這個句柄是不能繼承的。一般情況下,這個參數設置為NULL。

bManualReset:指定將創建的EVENT是自動復位還是手動復位。如果為TRUE,需要用ResetEvent(HANDLE)函數手動復位狀態為無信號,即一旦改EVENT被設置成有信號,則它會一直等到ResetEvent調用時才為無信號狀態。如果為FALSE,當一個有信號的等待線程被釋放后,系統會自動復位狀態為無信號狀態。

bInitialState:指定事件對象的初始狀態。如果為TRUE,初始狀態為有信號,否則為無信號。

lpName:? 事件對象的名稱,以字符串表示。名稱的長度受MAX_PATH的限制,名稱是大小寫敏感的。如果lpName匹配一個存在的命名的事件對象,函數將請求EVENT_ALL_ACCESS來訪問存在的對象。在這種情況下,bManualReset和bInitialState 被忽略,因為這兩個參數已經被存在的事件設置。如果lpEventAttributes參數不為NULL,這個參數可以決定是否句柄被繼承,但是它的安全描述(security-descriptor)成員被忽略。如果lpName 為NULL,創建一個沒有名稱的事件。如果lpName 匹配一個存在的semaphore, mutex, waitable timer, job或者file-mapping對象的名稱,函數調用失敗,GetLastError函數返回ERROR_INVALID_HANDLE。由于這些對象共享相同的命名空間,才導致這種情況的發生。

返回值:??? 函數返回句柄,該句柄具有EVENT_ALL_ACCESS權限去訪問新的事件對象,同時它可以在任何需要事件對象句柄的函數中使用。

??? 調用過程中的任何線程,都可以在一個等待函數中指定事件對象句柄。當指定的對象的狀態為有信號時,單對象等待函數(例如WaitForSingleObject)返回。對于多對象等待函數(例如WaitForMultipleObjects),可以指定為任意或所有指定的對象被置為有信號狀態。當等待函數返回時,等待線程將被釋放去繼續它的執行。?? 事件對象的初始狀態由bInitialState參數指定,用SetEvent函數可以設置對象為有信號狀態,用ResetEvent函數可以設置對象為無信號狀態。?? 當一個手動復原的事件對象的狀態被置為有信號狀態時,該對象將一直保持有信號狀態,直至明確調用ResetEvent函數將其置為無符號狀態。當事件對象被設置為有信號狀態時,任何數量的等待線程或者隨后等待的線程都會被釋放。

??? 當一個自動復原事件對象的狀態被設置為有信號狀態時,該對象一直保持有信號狀態,直至一個單等待線程被釋放;系統然后會自動重置對象到無信號狀態。???

多個進程可持有同一個事件對象的多個句柄,可以通過使用此對象來實現進程間的同步。下面的對象共享機制是可行的:

  ·在CreateEvent函數中,lpEventAttributes參數指定句柄可被繼承時,通過CreateProcess函數創建的子進程繼承的事件對象句柄。

  ·一個進程可以在DuplicateHandle函數中指定事件對象句柄,從而獲得一個復制的句柄,此句柄可以被其它進程使用。

? ??? ·一個進程可以在OpenEvent或CreateEvent函數中指定一個名字,從而獲得一個有名的事件對象句柄。(在調用OpenEvent或CreateEvent函數時,一個進程可以指定事件對象的名字。)

  使用CloseHandle函數關閉句柄。當進程終止時,系統將自動關閉句柄。事件對象會被銷毀,當最后一個句柄被關閉。

?

二、c++CreateEvent函數在多線程中使用及實例

?

下面主要演示一下采用CreateEvent實現多線程。

例子很簡單,主要測試CreateEvent中bManualReset:和bInitialState參數的取值在線程調用中信號狀態的情況。

?

測試1:

bManualReset:TRUE
bInitialState:TRUE

CreateEvent(NULL, TRUE, TRUE, NULL); //使用手動重置為無信號狀態,初始化時有信號狀態

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>; //使用手動重置為無信號狀態,初始化時有信號狀態 //hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); //當一個等待線程被釋放時,自動重置為無信號狀態,初始是有信號狀態 //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; }


執行結果:

?

從結果中看,執行完線程1又執行了線程2.

由于hEvent = CreateEvent(NULL, TRUE, TRUE, NULL),使用手動重置為無信號狀態,初始化時有信號狀態

所以hEvent一直處于有信號狀態,無論是線程1釋放后,hEvent仍處于有信號狀態,所以線程2正常執行了。

?

測試2:

bManualReset:FALSE
bInitialState:TRUE

?

hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); //當一個等待線程被釋放時,自動重置為無信號狀態,初始是有信號狀態


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); //使用手動重置為無信號狀態,初始化時有信號狀態 hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); </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; }

執行結果:

?

從執行結果中分析,執行了線程1,線程2一直在等待,直到主線程結束。

由于hEvent = CreateEvent(NULL, FALSE, TRUE, NULL),當一個等待線程被釋放時,自動重置為無信號狀態,初始是有信號狀態

初始執行線程1的時候,hEvent是有信號的,所以線程1正常執行;又由于bManualReset=FALSE,所以執行完線程1后,hEven

?

WaitForSingleObject(hEvent,INFINITE);


函數一直在等待hEvent變為有信號狀態,但是當主線程執行完,還沒等待到,線程2程序一直沒有走下去。

?

?

測試3:

bManualReset:TRUE
bInitialState:FALSE

hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//使用手動重置為無信號狀態,初始化時為無信號狀態

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); //使用手動重置為無信號狀態,初始化時有信號狀態 //hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); //當一個等待線程被釋放時,自動重置為無信號狀態,初始是有信號狀態 hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//使用手動重置為無信號狀態,初始化時為無信號狀態</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; }

執行結果,可想而知,只能輸出:
in?thread1@!?
in?thread2@!?
因為初始為無信號狀態,所以hEvent一直處于無信號狀態,因此這兩個線程一直在等待,直到主線程結束。

?

修改:放開例子中的注釋部分:

if (SetEvent(hEvent))//設置信號為有信號狀態
{
cout << "setEvent 成功" <<endl;
}

執行結果:

?

可見,線程1和線程2都執行了。

因為調用SetEvent,事件變為有信號狀態,線程1執行;又由于線程1釋放后,hEvent仍舊處于有信號狀態,所以線程2也執行了。

?

再修改:在線程1中,添加ResetEvent(hEvent)(手動設置事件為無信號狀態),則線程2不會執行。

?

測試4:

bManualReset:FALSE
bInitialState:FALSE

hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);//線程釋放后自動重置為無信號狀態,初始化時為無信號狀態

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); //使用手動重置為無信號狀態,初始化時有信號狀態 //hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); //當一個等待線程被釋放時,自動重置為無信號狀態,初始是有信號狀態 //hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//使用手動重置為無信號狀態,初始化時為無信號狀態 hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);//使用手動重置為無信號狀態,初始化時為無信號狀態 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; }

?

?

?

由于調用SetEvent,hEvent為有信號狀態,線程1正常執行,又由于調用完線程1后,hEvent自動重置為無信號狀態,所以線程2只能在等待,直到主線程退出。

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

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。