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 上的一些开发陷阱,常常会导致程序问题不穷,死锁不断.本文中我们 ...
随机推荐
- FZU 1686(重复覆盖)
题目连接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=31370 题意:用尽量少r*c的小矩形覆盖大矩形n*m中的所有1,将 ...
- GString及IntelliJIdea中调试Groovy的操作步骤
今天是学习Groovy的第一天,首先我觉得学习任何一种语言都要先弄清楚这种语言的特性,因为只有了解了特性之后学习才能达到好的效果,那么groovy的特点是什么的.我觉得groovy是一种动态语言,动态 ...
- 控制台打印Hibernate的SQL语句显示绑定参数值
问题? 使用Hibernate提供的show_sql内置属性true只能输出类似于下面的SQL语句:Hibernate: insert into user(name,password) value ...
- Android permission 访问权限
程序执行需要读取到安全敏感项必需在androidmanifest.xml中声明相关权限请求, 完整列表如下: android.permission.ACCESS_CHECKIN_PROPERTIES ...
- Visual Studio跨平台开发实战(3) - Xamarin iOS多页面应用程式开发
原文 Visual Studio跨平台开发实战(3) - Xamarin iOS多页面应用程式开发 前言 在前一篇教学中, 我们学会如何使用Visual Studio 搭配Xcode 进行iOS基本控 ...
- Windows Phone开发(44):推送通知第二集——磁贴通知
原文:Windows Phone开发(44):推送通知第二集--磁贴通知 前面我们说了第一个类型--Toast通知,这玩意儿不知大家是不是觉得很新鲜,以前玩.NET编程应该没接触过吧? 其实这东西绝对 ...
- 修改linux系统时间、rtc时间以及时间同步
修改linux的系统时间用date -s [MMDDhhmm[[CC]YY][.ss]] 但是系统重启就会从新和硬件时钟同步. 要想永久修改系统时间,就需要如下命令:hwclock hwclock - ...
- VS2010关于error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
前段时间自己的系统一直在安装更新.今天突然打开VS2010当运行的时候一直出现error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏这种错误.然后就百度 解决的方法: 1.项目\属 ...
- 树形dp专辑
hdu 2196 http://acm.hdu.edu.cn/showproblem.php?pid=2196 input 5//5个结点 1 1//表示结点2到结点1有一条权值为1的边 2 1//表 ...
- bzoj1001/BJOI2006 灰太狼抓到的兔子
1001: [BeiJing2006]狼抓兔子(id=1001">传送门) 图论新知识..没学过.. 平面图最小割等于对偶图的最短路 详见课件:http://wenku.baidu.c ...