CreateEvent函數詳解參見本博客文章:
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
LPCSTR lpName
);
bManualReset:TRUE,使用ResetEvent()手動重置爲無信號狀態;FALSE,當一個等待線程被釋放時,自動重置狀態爲無信號狀態。
bInitialState:指定事件對象的初始狀態,當TRUE,初始狀態爲有信號狀態;當FALSE,初始狀態爲無信號狀態。
下面主要演示一下采用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[])
- {
- <span style="color:#ff0000;">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); //使用手動重置爲無信號狀態,初始化時有信號狀態
- <span style="color:#ff0000;">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後,hEvent自動重置爲無信號狀態,所以在線程2中,
- WaitForSingleObject(hEvent,INFINITE);
測試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); //當一個等待線程被釋放時,自動重置爲無信號狀態,初始是有信號狀態
- <span style="color:#ff0000;">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@!
修改:放開例子中的註釋部分:
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 都會執行。