C++多线程Event方法使用及实例(简单汇总)

由于多线程中event方法平时很少用到,以前偶尔用下也是临时到网上搜下代码,没有细细去理解,所以用完没几天就忘记了,今天又再次遇到需要event的问题,所以觉得有必要学习并整理下,下面是我在学习过程中百度到的两篇文章,反正我是学明白了,希望也能帮助到大家。

c++中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

 

[cpp] view plain copy 
  1. #include "iostream"

  2. #include "windows.h"

  3. usingnamespace std;  

  4. DWORD WINAPI ThreadProc1(LPVOID lpParam);  

  5. DWORD WINAPI ThreadProc2(LPVOID lpParam);  

  6. HANDLE hEvent = NULL;  

  7. HANDLE hThread1 = NULL;  

  8. HANDLE hThread2 = NULL;  

  9. int main(int argc, char *args[])  

  10. {  

  11.     <span style="color:#ff0000;">hEvent = CreateEvent(NULL, TRUE, TRUE, NULL)</span>; //使用手动重置为无信号状态,初始化时有信号状态

  12. //hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); //当一个等待线程被释放时,自动重置为无信号状态,初始是有信号状态

  13. //if (SetEvent(hEvent))

  14. //{

  15. //  cout << "setEvent 成功" <<endl;

  16. //}

  17.     hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc1, NULL, 0,NULL);  

  18.     Sleep(200);  

  19.     hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc2, NULL, 0,NULL);  

  20.     Sleep(200);  

  21. if ( NULL == hThread1)  

  22.     {  

  23.         cout <<"create thread fail!";  

  24.     }  

  25. //DWORD dCount = ResumeThread(hThread);

  26. //cout << LOWORD(dCount) << endl;

  27. return 0;  

  28. }  

  29. DWORD WINAPI ThreadProc1(LPVOID lpParam)  

  30. {  

  31.     cout <<"in thread1@!"<<endl;  

  32. DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);  

  33. if ( WAIT_OBJECT_0 == dReturn)  

  34.     {  

  35.         cout <<" thread1 signaled ! "<<endl;  

  36.     }  

  37.     cout <<"in thread1 --signal"<<endl;  

  38. //SetEvent(hEvent);

  39. return 0;  

  40. }  

  41. DWORD WINAPI ThreadProc2(LPVOID lpParam)  

  42. {  

  43.     cout <<"in thread2@!"<<endl;  

  44. DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);  

  45. if ( WAIT_OBJECT_0 == dReturn)  

  46.     {  

  47.         cout <<"thread2 signaled ! "<<endl;  

  48.     }  

  49.     cout <<"in thread2--signal"<<endl;  

  50. return 0;  

  51. }  


执行结果: 

 


从结果中看,执行完线程1又执行了线程2.

由于hEvent = CreateEvent(NULL, TRUE, TRUE, NULL),使用手动重置为无信号状态,初始化时有信号状态

所以hEvent一直处于有信号状态,无论是线程1释放后,hEvent仍处于有信号状态,所以线程2正常执行了。


测试2:

bManualReset:FALSE
bInitialState:TRUE

[cpp] view plain copy 
  1. hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); //当一个等待线程被释放时,自动重置为无信号状态,初始是有信号状态

example2.cpp

[cpp] view plain copy 
  1. #include "iostream"

  2. #include "windows.h"

  3. usingnamespace std;  

  4. DWORD WINAPI ThreadProc1(LPVOID lpParam);  

  5. DWORD WINAPI ThreadProc2(LPVOID lpParam);  

  6. HANDLE hEvent = NULL;  

  7. HANDLE hThread1 = NULL;  

  8. HANDLE hThread2 = NULL;  

  9. int main(int argc, char *args[])  

  10. {  

  11. //hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); //使用手动重置为无信号状态,初始化时有信号状态

  12.     <span style="color:#ff0000;">hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); </span>//当一个等待线程被释放时,自动重置为无信号状态,初始是有信号状态

  13. //if (SetEvent(hEvent))

  14. //{

  15. //  cout << "setEvent 成功" <<endl;

  16. //}

  17.     hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc1, NULL, 0,NULL);  

  18.     Sleep(200);  

  19.     hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc2, NULL, 0,NULL);  

  20.     Sleep(200);  

  21. if ( NULL == hThread1)  

  22.     {  

  23.         cout <<"create thread fail!";  

  24.     }  

  25. //DWORD dCount = ResumeThread(hThread);

  26. //cout << LOWORD(dCount) << endl;

  27. return 0;  

  28. }  

  29. DWORD WINAPI ThreadProc1(LPVOID lpParam)  

  30. {  

  31.     cout <<"in thread1@!"<<endl;  

  32. DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);  

  33. if ( WAIT_OBJECT_0 == dReturn)  

  34.     {  

  35.         cout <<" thread1 signaled ! "<<endl;  

  36.     }  

  37.     cout <<"in thread1 --signal"<<endl;  

  38. //SetEvent(hEvent);

  39. return 0;  

  40. }  

  41. DWORD WINAPI ThreadProc2(LPVOID lpParam)  

  42. {  

  43.     cout <<"in thread2@!"<<endl;  

  44. DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);  

  45. if ( WAIT_OBJECT_0 == dReturn)  

  46.     {  

  47.         cout <<"thread2 signaled ! "<<endl;  

  48.     }  

  49.     cout <<"in thread2--signal"<<endl;  

  50. return 0;  

  51. }  

执行结果: 

 


从执行结果中分析,执行了线程1,线程2一直在等待,直到主线程结束。

由于hEvent = CreateEvent(NULL, FALSE, TRUE, NULL),当一个等待线程被释放时,自动重置为无信号状态,初始是有信号状态

初始执行线程1的时候,hEvent是有信号的,所以线程1正常执行;又由于bManualReset=FALSE,所以执行完线程1后,hEvent自动重置为无信号状态,所以在线程2中,

[cpp] view plain copy 
  1. WaitForSingleObject(hEvent,INFINITE);  

函数一直在等待hEvent变为有信号状态,但是当主线程执行完,还没等待到,线程2程序一直没有走下去。 

 


测试3:

bManualReset:TRUE
bInitialState:FALSE

hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//使用手动重置为无信号状态,初始化时为无信号状态

example3.cpp

[cpp] view plain copy 
  1. #include "iostream"

  2. #include "windows.h"

  3. usingnamespace std;  

  4. DWORD WINAPI ThreadProc1(LPVOID lpParam);  

  5. DWORD WINAPI ThreadProc2(LPVOID lpParam);  

  6. HANDLE hEvent = NULL;  

  7. HANDLE hThread1 = NULL;  

  8. HANDLE hThread2 = NULL;  

  9. int main(int argc, char *args[])  

  10. {  

  11. //hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); //使用手动重置为无信号状态,初始化时有信号状态

  12. //hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); //当一个等待线程被释放时,自动重置为无信号状态,初始是有信号状态

  13.     <span style="color:#ff0000;">hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//使用手动重置为无信号状态,初始化时为无信号状态</span>

  14. //if (SetEvent(hEvent))

  15. //{

  16. //  cout << "setEvent 成功" <<endl;

  17. //}

  18.     hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc1, NULL, 0,NULL);  

  19.     Sleep(200);  

  20.     hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc2, NULL, 0,NULL);  

  21.     Sleep(200);  

  22. if ( NULL == hThread1)  

  23.     {  

  24.         cout <<"create thread fail!";  

  25.     }  

  26. //DWORD dCount = ResumeThread(hThread);

  27. //cout << LOWORD(dCount) << endl;

  28. return 0;  

  29. }  

  30. DWORD WINAPI ThreadProc1(LPVOID lpParam)  

  31. {  

  32.     cout <<"in thread1@!"<<endl;  

  33. DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);  

  34. if ( WAIT_OBJECT_0 == dReturn)  

  35.     {  

  36.         cout <<" thread1 signaled ! "<<endl;  

  37.     }  

  38.     cout <<"in thread1 --signal"<<endl;  

  39. //SetEvent(hEvent);

  40. return 0;  

  41. }  

  42. DWORD WINAPI ThreadProc2(LPVOID lpParam)  

  43. {  

  44.     cout <<"in thread2@!"<<endl;  

  45. DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);  

  46. if ( WAIT_OBJECT_0 == dReturn)  

  47.     {  

  48.         cout <<"thread2 signaled ! "<<endl;  

  49.     }  

  50.     cout <<"in thread2--signal"<<endl;  

  51. return 0;  

  52. }  


执行结果,可想而知,只能输出:

[cpp] view plain copy 
  1. in thread1@!  

[cpp] view plain copy 
  1. 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

 

[cpp] view plain copy 
  1. #include "iostream"

  2. #include "windows.h"

  3. usingnamespace std;  

  4. DWORD WINAPI ThreadProc1(LPVOID lpParam);  

  5. DWORD WINAPI ThreadProc2(LPVOID lpParam);  

  6. HANDLE hEvent = NULL;  

  7. HANDLE hThread1 = NULL;  

  8. HANDLE hThread2 = NULL;  

  9. int main(int argc, char *args[])  

  10. {  

  11. //hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); //使用手动重置为无信号状态,初始化时有信号状态

  12. //hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); //当一个等待线程被释放时,自动重置为无信号状态,初始是有信号状态

  13. //hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//使用手动重置为无信号状态,初始化时为无信号状态

  14.     hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);//使用手动重置为无信号状态,初始化时为无信号状态

  15. if (SetEvent(hEvent))  

  16.     {  

  17.         cout << "setEvent 成功" <<endl;  

  18.     }  

  19.     hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc1, NULL, 0,NULL);  

  20.     Sleep(200);  

  21.     hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc2, NULL, 0,NULL);  

  22.     Sleep(200);  

  23. if ( NULL == hThread1)  

  24.     {  

  25.         cout <<"create thread fail!";  

  26.     }  

  27. //DWORD dCount = ResumeThread(hThread);

  28. //cout << LOWORD(dCount) << endl;

  29. return 0;  

  30. }  

  31. DWORD WINAPI ThreadProc1(LPVOID lpParam)  

  32. {  

  33.     cout <<"in thread1@!"<<endl;  

  34. DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);  

  35. if ( WAIT_OBJECT_0 == dReturn)  

  36.     {  

  37.         cout <<" thread1 signaled ! "<<endl;  

  38.     }  

  39.     cout <<"in thread1 --signal"<<endl;  

  40. //SetEvent(hEvent);

  41. return 0;  

  42. }  

  43. DWORD WINAPI ThreadProc2(LPVOID lpParam)  

  44. {  

  45.     cout <<"in thread2@!"<<endl;  

  46. DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);  

  47. if ( WAIT_OBJECT_0 == dReturn)  

  48.     {  

  49.         cout <<"thread2 signaled ! "<<endl;  

  50.     }  

  51.     cout <<"in thread2--signal"<<endl;  

  52. return 0;  

  53. }  


执行结果: 

 


由于调用SetEvent,hEvent为有信号状态,线程1正常执行,又由于调用完线程1后,hEvent自动重置为无信号状态,所以线程2只能在等待,直到主线程退出。

修改:线程1中的SetEvent(hEvent);的注释去掉,再运行,则线程1和线程2 都会执行。

此篇文章链接地址:http://blog.csdn.net/chen825919148/article/details/7904289

 

下一篇文章不在于讲解,我给链接的目的是让大家起到练兵的效果,地址:http://blog.sina.com.cn/s/blog_625eda0b0100xa6p.html 内容就不贴了。

你可能感兴趣的:(event事件,手动设置,createEvent,自动设置,信号状态,C++多线程)