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

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

    IKVM.NET是一个针对Mono和微软.net框架的java实现,其设计目的是在.NET平台上运行java程序.本文将比较详细的介绍这个工具的原理.使用入门(如何java应用转换为.NET应用.), ...

  2. 美版SOLOWHEEL与盗版SOLOWHEEL-IPS独轮车终极PK【图】_厂商资讯_太平洋电脑网

    http://g.pconline.com.cn/x/330/3304676.html

  3. HDU 3046Pleasant sheep and big big wolf(切最小网络流)

    职务地址:HDU 3046 最小割第一发!事实上也没什么发不发的. ..最小割==最大流.. 入门题,可是第一次入手最小割连入门题都全然没思路... sad..对最小割的本质还是了解的不太清楚.. 这 ...

  4. JSTL自定义标签库 (二)

    要定义自己的标签,首先写个java类,extends TagSupport  或者 implements Tag ,然后在类体里实现自己想要的方法,或者覆盖父类的方法. 我定义的MyTag代码如下: ...

  5. 数字证书及CA的扫盲介绍(转)

    ★ 先说一个通俗的例子 考虑到证书体系的相关知识比较枯燥.晦涩.俺先拿一个通俗的例子来说事儿. ◇ 普通的介绍信 想必大伙儿都听说过介绍信的例子吧?假设 A 公司的张三先生要到 B 公司去拜访,但是 ...

  6. uvalive 2088 - Entropy(huffman编码)

    题目连接:2088 - Entropy 题目大意:给出一个字符串, 包括A~Z和_, 现在要根据字符出现的频率为他们进行编码,要求编码后字节最小, 然后输出字符均为8字节表示时的总字节数, 以及最小的 ...

  7. VC中Tab control的用法

    1. 新建一个MFC工程, 取名MyTab, 选择Dialog based, 然后Finish. 2. 删除对话框上默认添加的三个控件. 添加Tab Control控件并在Property属性中设置I ...

  8. Jsoup 抓取和数据页 认识HTTP头

    推荐一本书:黑客攻防技术宝典.Web实战篇  :       顺便留下一个疑问:能否通过jsoup大量并发訪问web或者小型域名server,使其瘫痪?其有用jsoup熟悉的朋友能够用它解析url来干 ...

  9. 从lca到树链剖分 bestcoder round#45 1003

    bestcoder round#45 1003 题,给定两个点,要我们求这两个点的树上路径所经过的点的权值是否出现过奇数次.如果是一般人,那么就是用lca求树上路径,然后判断是否出现过奇数次(用异或) ...

  10. leetcode第一刷_Pow(x, n)

    高速乘方的算法,写了好多变,出了各种错,真是服了我自己了. 思想是每次对n减半,将当前的temp平方.须要注意的是假设当前的n是个奇数,减半之后会丢失掉一次乘积,因此假设当前的n为奇数,应该先在结果里 ...