CreateEvent函数

CreateEvent函数

CreateEvent函数常用于线程的同步。

以下是事件在多线程中的应用:
事件对象就像一个开关:它只有两种状态开和关。当一个事件处于”开”状态,我们称其为”有信号”否则称为”无信号”。可以在一个线程的执行函数中创建一个事件对象,然后观察它的状态,如果是”无信号”就让该线程睡眠,这样该线程占用的CPU时间就比较少。

CreateEvent函数原型:
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
LPCSTR lpName
);

  • bManualReset:TRUE,使用ResetEvent()手动重置为无信号状态;FALSE,当一个等待线程被释放时,自动重置状态为无信号状态。
  • bInitialState:指定事件对象的初始状态,当TRUE,初始状态为有信号状态;当FALSE,初始状态为无信号状态。

四个例子演示采用CreateEvent实现多线程:

例子很简单,主要测试CreateEvent中bManualReset和bInitialState参数的取值在线程调用中信号状态的情况。
需要用到的函数:SetEvent、ResetEvent和WaitForSingleObject,函数原型如下:

  • BOOL SetEvent(HANDLE hEvent);
  • BOOL ResetEvent(HANDLE hEvent);
  • DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds);

WaitForSingleObject简介:WaitForSingleObject()等待,直到参数所指定的OBJECT成为发信号状态时才返回,OBJECT可以是EVENT,也可以是其它内核对象。 当你创建一个线程时,其实那个线程是一个循环,不像上面那样只运行一次的。这样就带来了一个问题,在那个死循环里要找到合适的条件退出那个死循环,那么是怎么样实现它的呢?在Windows里往往是采用事件的方式,当然还可以采用其它的方式。在这里先介绍采用事件的方式来通知从线程运行函数退出来,它的实现原理是这样,在那个死循环里不断地使用WaitForSingleObject函数来检查事件是否满足,如果满足就退出线程,不满足就继续运行。当在线程里运行阻塞的函数时,就需要在退出线程时,先要把阻塞状态变成非阻塞状态,比如使用一个线程去接收网络数据,同时使用阻塞的SOCKET时,那么要先关闭SOCKET,再发送事件信号,才可以退出线程的。(来源于百度百科)

例子一:
bManualReset:TRUE
bInitialState:TRUE
CreateEvent(NULL, TRUE, TRUE, NULL); //使用手动重置为无信号状态,初始化时有信号状态

例子二:
bManualReset:FALSE
bInitialState:TRUE
hEvent = CreateEvent(NULL, FALSE, TRUE, NULL); //当一个等待线程被释放时,自动重置为无信号状态,初始是有信号状态

例子三:
bManualReset:TRUE
bInitialState:FALSE
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//使用手动重置为无信号状态,初始化时为无信号状态

例子四:
bManualReset:FALSE
bInitialState:FALSE
hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);//线程释放后自动重置为无信号状态,初始化时为无信号状态

例子一如下,请举一反三查看其他示例:
[cpp]#include “iostream”
#include “windows.h”
using namespace std;

DWORD WINAPI ThreadProc1(LPVOID lpParam);
DWORD WINAPI ThreadProc2(LPVOID lpParam);
HANDLE hEvent = NULL;
HANDLE hThread1 = NULL;
HANDLE hThread2 = NULL;
int main(int argc, char *args[])
{
hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); //使用手动重置为无信号状态,初始化时有信号状态
hThread1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc1, NULL, 0,NULL);
Sleep(200);
hThread2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadProc2, NULL, 0,NULL);
Sleep(200);
if ( NULL == hThread1)
{
cout <<“create thread fail!”;
}

return 0;
}
DWORD WINAPI ThreadProc1(LPVOID lpParam)
{
cout <<“in thread1@!”<<endl;

DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);

if ( WAIT_OBJECT_0 == dReturn)
{
cout <<” thread1 signaled ! “<<endl;
}
cout <<“in thread1 –signal”<<endl;

return 0;
}
DWORD WINAPI ThreadProc2(LPVOID lpParam)
{
cout <<“in thread2@!”<<endl;

DWORD dReturn = WaitForSingleObject(hEvent,INFINITE);

if ( WAIT_OBJECT_0 == dReturn)
{
cout <<“thread2 signaled ! “<<endl;
}
cout <<“in thread2–signal”<<endl;

return 0;
}[/cpp]

运行结果:

createvent函数
createvent函数

参考资料:c++中CreateEvent函数详解及实例 (互联网)和 百度百科

One Reply to “CreateEvent函数”