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. }  


执行结果:  

 

1334672684_7600.png

从结果中看,执行完线程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. }  

执行结果:  

 

1334673026_6295.png
从执行结果中分析,执行了线程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;
}

执行结果:

1334673757_4213.png

可见,线程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. }  


执行结果:  

 

1334674052_1523.png

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

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










本文转自 我不会抽烟 51CTO博客,原文链接:http://blog.51cto.com/zhouhongyu1989/1225702,如需转载请自行联系原作者

目录
相关文章
|
1月前
|
存储 前端开发 Java
【C++ 多线程 】C++并发编程:精细控制数据打印顺序的策略
【C++ 多线程 】C++并发编程:精细控制数据打印顺序的策略
45 1
|
30天前
|
数据可视化 关系型数据库 编译器
【C/C++ 单线程性能分析工具 Gprof】 GNU的C/C++ 性能分析工具 Gprof 使用全面指南
【C/C++ 单线程性能分析工具 Gprof】 GNU的C/C++ 性能分析工具 Gprof 使用全面指南
106 2
|
28天前
|
存储 算法 Java
【C/C++ 线程池设计思路】 深入探索线程池设计:任务历史记录的高效管理策略
【C/C++ 线程池设计思路】 深入探索线程池设计:任务历史记录的高效管理策略
72 0
|
30天前
|
消息中间件 Linux 调度
【Linux 进程/线程状态 】深入理解Linux C++中的进程/线程状态:阻塞,休眠,僵死
【Linux 进程/线程状态 】深入理解Linux C++中的进程/线程状态:阻塞,休眠,僵死
67 0
|
5天前
使用代理IP池实现多线程的方法
使用代理IP池实现多线程的方法
|
25天前
|
Java 测试技术 Python
Python开启线程和线程池的方法
Python开启线程和线程池的方法
17 0
Python开启线程和线程池的方法
|
28天前
|
存储 算法 数据管理
C++中利用随机策略优化二叉树操作效率的实现方法
C++中利用随机策略优化二叉树操作效率的实现方法
77 1
|
28天前
|
安全 Java 调度
【C/C++ 线程池设计思路 】设计与实现支持优先级任务的C++线程池 简要介绍
【C/C++ 线程池设计思路 】设计与实现支持优先级任务的C++线程池 简要介绍
43 2
|
28天前
|
Linux API C++
【C++ 线程包裹类设计】跨平台C++线程包装类:属性设置与平台差异的全面探讨
【C++ 线程包裹类设计】跨平台C++线程包装类:属性设置与平台差异的全面探讨
51 2
|
28天前
|
设计模式 安全 C++
【C++ const 函数 的使用】C++ 中 const 成员函数与线程安全性:原理、案例与最佳实践
【C++ const 函数 的使用】C++ 中 const 成员函数与线程安全性:原理、案例与最佳实践
71 2