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 上的一些开发陷阱,常常会导致程序问题不穷,死锁不断.本文中我们 ...
随机推荐
- Cocos2d-x Tiled地图编辑器(一)基本使用
Tiled地图编辑器支持普通视角地图和45度角地图, 它生成的地图数据文件cocos2d-x完美的支持,Tiled地图编辑器是一个以普通使用为目标地图编辑器,它使用简单而且能够轻松地在不同的游戏引擎中 ...
- c语言来实现c++
闲来没事,看了看sqlite的源代码,突然想用c实现c++,写了例如以下demo,自我感觉不错 #include <stdio.h> #include <stdlib.h> s ...
- ORA-16525: the Data Guard broker is not yet available
DGMGRL> disable configuration;ORA-16525: the Data Guard broker is not yet available Configuration ...
- FAAC1.28 在海思HI3520D/HI3515A平台linux中的编译 优化
FAAC1.28的下载地址:http://www.audiocoding.com/downloads.html 怎样编译: 1../configure --host=arm-hisiv100nptl- ...
- Python的包管理
0.Python的包管理 在刚开始学习Python的时候比较头疼各种包的管理,后来搜到一些Python的包管理工具,比如setuptools, easy_install, pip, distribut ...
- Qt4.8在Windows下的三种编程环境搭建
Qt4.8在Windows下的三种编程环境搭建 Qt的版本是按照不同的图形系统来划分的,目前分为四个版本:Win32版,适用于Windows平台:X11版,适合于使用了X系统的各种Linux和Unix ...
- hihocoder第42周 3*N骨牌覆盖(状态dp+矩阵快速幂)
http://hihocoder.com/contest/hiho42/problem/1 给定一个n,问我们3*n的矩阵有多少种覆盖的方法 第41周做的骨牌覆盖是2*n的,状态转移方程是dp[i] ...
- hdu 5073 Galaxy(2014acm鞍山亚洲分部 C)
主题链接:http://acm.hdu.edu.cn/showproblem.php? pid=5073 Galaxy Time Limit: 2000/1000 MS (Java/Others) ...
- 深入了解mysql它BDB系列(1)---BDB基础知识
深入了解mysql它BDB系列(1) ---BDB关基础知识 作者:杨万富 一:BDB体系结构 1.1.BDB体系结构 BDB总体的体系结构如图1.1所看到的.包括五个子系统(见图1.1中 ...
- 优化移动设备上SharePoint 2013网站
优化移动设备上SharePoint 2013网站 本文由SPFarmer翻译自Waldek Mastykarz的文章 移动市场在持续的增长.在不远的将来,使用移动设备浏览站点将会超过电脑.为了保证用户 ...