CreateEvent是创建windows事件对象,作用主要用在判断线程退出和锁定方面.
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTESlpEventAttributes, // SD
BOOLbManualReset, // reset type
BOOLbInitialState, // initial state
LPCTSTRlpName // object name);
参数说明:
lpEventAttributes:
[输入]一个指向SECURITY_ATTRIBUTES结构的指针,确定返回的句柄是否可被子进程继承。如果lpEventAttributes是NULL,此句柄不能被继承。
Windows NT/2000:lpEventAttributes的结构中的成员为新的事件指定了一个安全符。如果lpEventAttributes是NULL,事件将获得一个默认的安全符。
bManualReset:
[输入]指定将事件对象创建成手动复原还是自动复原。如果是TRUE,那么必须用ResetEvent函数来手工将事件的状态复原到无信号状态。如果设置为FALSE,当事件被一个等待线程释放以后,系统将会自动将事件状态复原为无信号状态。
bInitialState:
[输入]指定事件对象的初始状态。如果为TRUE,初始状态为有信号状态;否则为无信号状态。
lpName:
[输入]指定事件的对象的名称,是一个以0结束的字符串指针。名称的字符格式限定在MAX_PATH之内。名字是对大小写敏感的。
如果lpName指定的名字,与一个存在的命名的事件对象的名称相同,函数将请求EVENT_ALL_ACCESS来访问存在的对象。这时候,由于 bManualReset和bInitialState参数已经在创建事件的进程中设置,这两个参数将被忽略。如果lpEventAttributes是参数不是NULL,它将确定此句柄是否可以被继承,但是其安全描述符成员将被忽略。
如果lpName为NULL,将创建一个无名的事件对象。
如果lpName的和一个存在的信号、互斥、等待计时器、作业或者是文件映射对象名称相同,函数将会失败,在GetLastError函数中将返回ERROR_INVALID_HANDLE。造成这种现象的原因是这些对象共享同一个命名空间。
以火车票订票系统为例:
// CreateEvent.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
#include <iostream>
#include <string>
using namespace std;
DWORD WINAPI Fun1Proc (LPVOID lpParameter);
DWORD WINAPI Fun2Proc (LPVOID lpParameter);
int tickets=100;
HANDLE g_hEvent;
void main()
{
HANDLE hThread1,hThread2;
HANDLE g_hEvent1;
g_hEvent1=CreateEvent(NULL,FALSE,FALSE,_T("tickets")); //让应用程序只能有一个实例
if(g_hEvent1)
{
if(ERROR_ALREADY_EXISTS==GetLastError())
{
cout<<"only one instance can run !"<<endl;
return;
}
}
g_hEvent=CreateEvent(NULL,FALSE,TRUE,NULL); //创建自动重置事件内核对象,非信号状态
hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);
hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);
CloseHandle(hThread1); //关闭句柄没有终止线程,标示主线程对新线程的引用不感兴趣,引用计数减1
CloseHandle(hThread2);
//SetEvent(g_hEvent);
Sleep(4000);
CloseHandle(g_hEvent);
system("pause");
}
DWORD WINAPI Fun1Proc(LPVOID lpParameter) //当引用计数为0时,终止线程
{
while (TRUE)
{
WaitForSingleObject(g_hEvent,INFINITE);
//ResetEvent(g_hEvent);
if (tickets>0)
{
Sleep(1);
cout<<"thread1 sell tickes :"<<tickets--<<endl;
}
else
{
break;
}
//ResetEvent(g_hEvent);
SetEvent(g_hEvent);
}
return 0;
}
DWORD WINAPI Fun2Proc (LPVOID lpParameter)
{
while (TRUE)
{
WaitForSingleObject(g_hEvent,INFINITE);
//ResetEvent(g_hEvent);
if (tickets>0)
{
cout<<"thread2 sell tickes :"<<tickets--<<endl;
}
else
{
break;
}
//ResetEvent(g_hEvent);
SetEvent(g_hEvent);
}
return 0;
}