CreateEvent、SetEvent、ResetEvent和WaitForSingleObject
事件对象就像一个开关:它仅仅有两种状态---开和关。当一个事件处于”开”状态。我们称其为”有信号”。否则称为”无信号”。
能够在一个线程的运行函数中创建一个事件对象。然后观察它的状态,假设是”无信号”就让该线程睡眠。这样该线程占用的CPU时间就比較少。
产生事件对象的函数例如以下:
(1)CreateEvent
函数原型:
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全属性
BOOL bManualReset, // 复位方式
BOOL bInitialState, // 初始状态
LPCTSTR lpName // 对象名称
);
该函数创建一个Event同步对象,假设CreateEvent调用成功的话,会返回新生成的对象的句柄。否则返回NULL。
lpEventAttributes:一般为NULL
bManualReset:指定将事件对象创建成手动复原还是自己主动复原。
假设是TRUE(手动),那么就算等待线程处理了,必须用ResetEvent函数来手工才干将事件的状态复原到无信号状态。假设设置为FALSE(自己主动),当事件被一个等待线程处理并释放以后,系统会自己主动将事件状态复原为无信号状态。所以两者可用于不同的场合,自己主动复位的须要每次的事件信号才会执行,而手动复位的则能够一直执行。
bInitialState:指定事件对象的初始状态。假设为TRUE。初始状态为有信号状态;否则为无信号状态。
lpName:指定事件的对象的名称,在OpenEvent函数中可能使用。
演示样例代码:// 创建一个有名的。不能被继承的,手动复原,初始状态是无信号状态的事件对象:
Handle h = CreateEvent(NULL,TRUE,FALSE,“MyEvent”);
一个Event被创建以后,能够用OpenEvent()API来获得它的Handle,用CloseHandle()来关闭它,用SetEvent()或PulseEvent()来设置它使其有信号,用ResetEvent()来使其无信号,用WaitForSingleObject()或WaitForMultipleObjects()来等待其变为有信号.。
(2)SetEvent
函数原型:
BOOL WINAPI SetEvent(
__in HANDLE hEvent
);
设置事件的状态为有标记。
假设事件创建时是手工的,此事件将保持有标记直到调用ResetEvent。
假设事件是自己主动的,此事件将保持有标记,直到一个线程被释放,系统将设置事件的状态为无标记。
(3)ResetEvent
函数原型:
BOOL ResetEvent(
HANDLE hEvent
);
hEvent 指向事件对象的句柄。由 CreateEvent or OpenEvent 函数返回。这个句柄须要拥有EVENT_MODIFY_STATE 訪问权限。
函数成功,返回非0值,否则返回0值,能够调用GetLastError得到错误的具体信息。
这个函数用于手动重置事件对象。手动重置的对象在线程释放后必须手动置为无信号状态。自己主动重置的事件对象在一个等待它成功的线程释放后会自己主动变为无信号状态。
重置一个无信号的事件对象没有不论什么效果。
(4)WaitForSingleObject
函数原型:
DWORD WaitForSingleObject(
HANDLE hHandle,
DWORD dwMilliseconds
);
參数hHandle是一个事件的句柄,第二个參数dwMilliseconds是时间间隔。假设事件是有信号状态返回WAIT_OBJECT_0。假设事件超过dwMilliseconds值但事件还是无信号状态,则返回WAIT_TIMEOUT。之前线程会一直堵塞程序在该语句处。
举例:
#include <windows.h>
#include <iostream>
#include <string>
#include <vector>
using namespace std; //通过事件得知还有一个线程的内部状态
//例:线程内部有三种状态:起床 吃饭 上班
HANDLE getupHandle;
HANDLE breakfastHandle;
HANDLE workHandle; vector<string> stateTexts;
DWORD WINAPI Worker(LPVOID n); int main()
{
stateTexts.reserve(3);//容器预留空间
getupHandle = CreateEvent(NULL, TRUE, FALSE, NULL);//手动。无信号
breakfastHandle = CreateEvent(NULL, TRUE, FALSE, NULL);
workHandle = CreateEvent(NULL, TRUE, FALSE, NULL); DWORD threadId;
HANDLE threadHandle = CreateThread(NULL,
0,
Worker,//线程入口函数
0,
0,
&threadId); WaitForSingleObject(getupHandle, INFINITE);
cout << stateTexts[0] << endl;
WaitForSingleObject(breakfastHandle, 3000);
cout << stateTexts[1] << endl;
WaitForSingleObject(workHandle, INFINITE);
cout << stateTexts[2] << endl; CloseHandle(threadHandle);
CloseHandle(getupHandle);
CloseHandle(breakfastHandle);
CloseHandle(workHandle); system("pause");
} DWORD WINAPI Worker(LPVOID n)
{
stateTexts.push_back("GetUp");
SetEvent(getupHandle);
stateTexts.push_back("Breakfast");
ResetEvent(breakfastHandle);
stateTexts.push_back("Work");
SetEvent(workHandle);
return 0;
}
执行结果:
先显示 GetUp。等待3000ms后显示Breakfast,接着立即显示Work
因为getupHandle和workHandle是设置为有信号的,它们的WaitForSingleObject直接有返回值
breakfastHandle设置为无信号的,它的WaitForSingleObject必须等待回报的完成时间值
版权声明:本文博主原创文章,博客,未经同意不得转载。
CreateEvent、SetEvent、ResetEvent和WaitForSingleObject的更多相关文章
- C++多线程的几个重要方法解析CreateEvent / SetEvent /ResetEvent/ 等
1.CreateEvent 是创建windows事件的意思,作用主要用在判断线程退出,程锁定方面. 函功能描述:创建或打开一个命名的或无名的事件对象. HANDLE m_hExit; m_hExit= ...
- SetEvent/ResetEvent
在自己主动重置事件对象中,当WaitSingleObject/WaitForMultipleObjects接收到SetEvent发送过来的信号后则返回WAIT_OBJECT_0,此时操作系统(待定)自 ...
- delphi.thread.同步
注意:此文只是讲线程间的同步,其它同步不涉及. 线程同步是个好话题,因为写线程经常会遇到,所以就写写自己知道的东西. D里面,同步(特指线程同步)从线程的角度来分,有几种情况: 1:主线程与工作线程的 ...
- 零基础逆向工程38_Win32_12_信号量_线程控制小结
1 信号量 信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用.[百度百科] 1.1 创建信号量 HANDLE Create ...
- 线程中CreateEvent和SetEvent及WaitForSingleObject的用法
首先介绍CreateEvent是创建windows事件的意思,作用主要用在判断线程退出,线程锁定方面. CreateEvent 函功能描述:创建或打开一个命名的或无名的事件对象. EVENT有两种状态 ...
- CreateEvent和SetEvent及WaitForSingleObject的使用方法
CreateEvent: 1.函数功能: 创建一个命名或匿名的事件对象 2.函数原型: HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttri ...
- c++中SetEvent和ResetEvent的使用
关于事件 事件(Event)是WIN32提供的最灵活的线程间同步方式,事件可以处于激发状态(signaled or true)或未激发状态(unsignal or false).根据状态变迁方式的不同 ...
- 线程中的WaitForSingleObject和Event的用法
http://chinaxyw.iteye.com/blog/548622 首先介绍CreateEvent是创建windows事件的意思,作用主要用在判断线程退出,程锁定方面. CreateEvent ...
- [转]Linux 的多线程编程的高效开发经验
Linux 平台上的多线程程序开发相对应其他平台(比如 Windows)的多线程 API 有一些细微和隐晦的差别.不注意这些 Linux 上的一些开发陷阱,常常会导致程序问题不穷,死锁不断.本文中我们 ...
随机推荐
- 6.组函数(avg(),sum(),max(),min(),count())、多行函数,分组数据(group by,求各部门的平均工资),分组过滤(having和where),sql优化
1组函数 avg(),sum(),max(),min(),count()案例: selectavg(sal),sum(sal),max(sal),min(sal),count(sal) from ...
- MYSQL经常使用命令列表
MYSQL经常使用命令列表 1.系统管理 mysql -h主机地址 -uusername -p 连接MYSQL(在mysql/bin) exit 退出MYSQL命令 mysqladmin -uuser ...
- javaEE jdbc编程步骤
1.载入数据库驱动(jar文件) //须要下载一个数据库的jar包,并导入对应的JDBC项目中,创建路径! Class.forName("com.mysql.jdbc.Driver" ...
- hdu 5017 Ellipsoid(西安网络赛 1011)
Ellipsoid Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total ...
- Swift难点-继承中的构造规则实例具体解释
关于继承中的构造规则是一个难点. 假设有问题,请留言问我. 我的Swift新手教程专栏 http://blog.csdn.net/column/details/swfitexperience.html ...
- C语言 cgi(2)
1Columbia Universitycs3157 – Advanced ProgrammingSummer 2014, Lab #3, 40 pointsJune 10, 2014This lab ...
- freemarker 里 ?? 和 ? 都是什么意思
??是推断对象是否为空,比如:<#if object??>object对象不为空(即object存在)</#if> ?后面要加keyword,比如:<#if object ...
- veridata实验例(3)验证veridata发现insert操作不会导致同步
veridata实验例(3)验证veridata发现insert操作不会导致同步 续接:<veridata实验举例(2)验证表BONUS与表SALGRADE两节点同步情况>,地址:点击打开 ...
- Form表单中的action路径问题
今天刚接触web,在用jsp和servlet做一个简单的登陆的时候在Form表单action属性和method属性的一些问题: 我遇到的是Form表单提交到servelet处理时遇到的问题: (1 ...
- Linux使用快捷键,who命令,rm命令,ps命令,cd,命令kill命令,find命令,grep命令,tar命令(gz、tar、bz2),用户管理,vim配置的一部分,相关命令
1.进入Ubuntu开场后的终端窗口的快捷键是: ctrl + alt+t:通过这个命令能够打开终端. ctrl + alt+t:通过这个命令能够打开终端. 再开一个tab选项卡式 ...