事件对象就像一个开关:它仅仅有两种状态---开和关。当一个事件处于”开”状态。我们称其为”有信号”。否则称为”无信号”。

能够在一个线程的运行函数中创建一个事件对象。然后观察它的状态,假设是”无信号”就让该线程睡眠。这样该线程占用的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的更多相关文章

  1. C++多线程的几个重要方法解析CreateEvent / SetEvent /ResetEvent/ 等

    1.CreateEvent 是创建windows事件的意思,作用主要用在判断线程退出,程锁定方面. 函功能描述:创建或打开一个命名的或无名的事件对象. HANDLE m_hExit; m_hExit= ...

  2. SetEvent/ResetEvent

    在自己主动重置事件对象中,当WaitSingleObject/WaitForMultipleObjects接收到SetEvent发送过来的信号后则返回WAIT_OBJECT_0,此时操作系统(待定)自 ...

  3. delphi.thread.同步

    注意:此文只是讲线程间的同步,其它同步不涉及. 线程同步是个好话题,因为写线程经常会遇到,所以就写写自己知道的东西. D里面,同步(特指线程同步)从线程的角度来分,有几种情况: 1:主线程与工作线程的 ...

  4. 零基础逆向工程38_Win32_12_信号量_线程控制小结

    1 信号量 信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用.[百度百科] 1.1 创建信号量 HANDLE Create ...

  5. 线程中CreateEvent和SetEvent及WaitForSingleObject的用法

    首先介绍CreateEvent是创建windows事件的意思,作用主要用在判断线程退出,线程锁定方面. CreateEvent 函功能描述:创建或打开一个命名的或无名的事件对象. EVENT有两种状态 ...

  6. CreateEvent和SetEvent及WaitForSingleObject的使用方法

    CreateEvent: 1.函数功能: 创建一个命名或匿名的事件对象 2.函数原型: HANDLE CreateEvent(   LPSECURITY_ATTRIBUTES lpEventAttri ...

  7. c++中SetEvent和ResetEvent的使用

    关于事件 事件(Event)是WIN32提供的最灵活的线程间同步方式,事件可以处于激发状态(signaled or true)或未激发状态(unsignal or false).根据状态变迁方式的不同 ...

  8. 线程中的WaitForSingleObject和Event的用法

    http://chinaxyw.iteye.com/blog/548622 首先介绍CreateEvent是创建windows事件的意思,作用主要用在判断线程退出,程锁定方面. CreateEvent ...

  9. [转]Linux 的多线程编程的高效开发经验

    Linux 平台上的多线程程序开发相对应其他平台(比如 Windows)的多线程 API 有一些细微和隐晦的差别.不注意这些 Linux 上的一些开发陷阱,常常会导致程序问题不穷,死锁不断.本文中我们 ...

随机推荐

  1. 恩布企业 IM 安卓端 1.3,服务端 1.12 公布

    恩布企业IM的 Android 安卓开源手机client EntboostIM 公布 1.3 版本号.同一时候恩布IM服务端更新至 1.12 版本号; 安卓端主要更新内容: 添加收发手机文件功能: 登 ...

  2. 记得有一个奇怪的ORA-04028: cannot generate diana for object

    开发商称新一package,目前已经在翻译过程中的一些错误.提示PL/SQL:ORA-00942: table or view does not exists.这是一个非常明显的错误,即要么是表不存在 ...

  3. EBS并发管理器请求汇总(按照并发消耗时间,等待时间,平均等待事件等汇总)

    此数据集用于确定正在使用中并发管理器,并可与实际的在启动时分配的并发管理器.而且考虑完成状态为 正常/警告 的请求. select q.concurrent_queue_name, count(*) ...

  4. FBReaderJ源代码编译配置

    1.git路径:https://github.com/geometer/FBReaderJ.git 2.project中HowToBuild指引了怎么编译,补充一下: 须要在project文件夹和th ...

  5. Windows Phone开发(43):推送通知第一集——Toast推送

    原文:Windows Phone开发(43):推送通知第一集--Toast推送 好像有好几天没更新了,抱歉抱歉,最近"光荣"地失业,先是忙于寻找新去处,唉,暂时没有下文.而后又有一 ...

  6. Windows Phone开发(34):路径标记语法

    原文:Windows Phone开发(34):路径标记语法 如果你觉得前面所讨论的绘制各种几何图形的方法过于复杂,那么,今天我们也来一次"减负"吧.当然,我们是很轻松的,本教程是不 ...

  7. centos 64位编译安装 glibc-2.14

    cd /opt wget http://ftp.gnu.org/gnu/glibc/glibc-2.14.tar.gz tar -xzf glibc-2.14.tar.gz cd glibc-2.14 ...

  8. 【深入浅出jQuery】源码浅析--整体架构(转)

    最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...

  9. 查看文章strncpy()功能更好的文章

    strncpy()功能 原型:extern char *strncpy(char *dest, char *src, int n);    使用方法:#include <string.h> ...

  10. [C++] WinAES问题

    WinAES这是一个很好windows CAPI包. 假设C++项目需求和java程序aes加密和通信的解密,然后WinAES代码是有问题. java的aes默认代码未设置IV和用途ECB模式. 因此 ...