Windows API CreateEvent函数用法

本文介绍了Windows API中的CreateEvent函数,用于创建事件对象,主要用于线程退出和锁定的同步。该函数包括参数如lpEventAttributes、bManualReset、bInitialState和lpName,分别控制句柄继承、事件重置方式、初始状态和对象名称。在使用命名事件时,需要注意与其他命名对象的命名冲突。以火车票订票系统为实例,探讨了事件对象在实际场景中的应用。

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;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值