• 其他语言



如何使用 Win32* 函数管理事件对象
页面和feed选项
打印 | 通过电子邮件发送给朋友 | 联系支持中心
收藏此页
Digg此页 | 添加到您的del.icio.us帐号
给此页评分
论坛标签

搜索标签
 

挑战
应用 Win32* 函数创建和使用事件对象
事件对象为一个核心对象,始终保持无信号状态直至满足一个条件。程序员可将事件对象设置为有信号或无信号状态,这与互斥或信号量有所不同(其中对象的有信号和无信号状态由操作系统控制)。

事件对象的概念与条件变量非常相似,为程序员提供了最大灵活性来定义复杂的同步对象。事件类型有两种:手动重置事件与自动重置事件。手动重置事件只可由程序员重置返回至无信号状态,而自动重置事件在等待结束后即可返回至无信号状态。

解决方案

使用内置函数:
CreateEvent()、OpenEvent()、SetEvent()、ResetEvent() 以及 PulseEvent()。在 Win32* 中,可以通过调用 CreateEvent() 创建一个新事件(如果已创建,则使用 OpenEvent())。SetEvent() 函数用于将一个事件设置为有信号状态。在手动重置事件中调用 SetEvent() 函数时,所有的等待线程都被唤醒,除非经 ResetEvent() 函数特别设置,否则事件对象为有信号状态。

在自动重置事件中调用 SetEvent() 函数或 PulseEvent() 函数时,仅释放一个线程,事件重置为无信号状态。如果没有线程在等待,事件将保持有信号状态直至一个线程进入等待状态,随后事件转为无信号状态。在手动重置事件中调用 PulseEvent() 函数时,所有的等待线程均被唤醒,事件对象重置为无信号状态。

以下代码段显示了应如何使用事件:



//global variables
HANDLE g_hEvent = NULL;

//local variables
HANDLE hThread;
DWORD dwThreadID;
BOOL seteventStatus;

//create auto-reset event
g_hEvent = CreateEvent (NULL, // no security attributes
FALSE, //auto-reset event
FALSE, //initial state non-signaled
NULL); //name of the event object
If (g_hEvent)
//print error message
//exit (-1)
//create child threads
for (i=0; i<3; i++)
{
hThread=CreateThread(NULL,0,foo,(LPVOID)i,0,&dwThreadID);
if (hThread)
printf ("Thread launched successfully\n");
else
//print error message and exit (-1)
}
Sleep (1000);

//signal for auto reset event
seteventStatus = SetEvent (g_hEvent);
if (!seteventStatus)
//print error message for failing in calling set event and exit (-1)

//wait for child threads to exit
DWORD dwCThd = WaitForMultipleObjects (3, //count of objects
hThread, //thread handle
TRUE, //wait for all
INFINITE); //time out interval
If (dwCThd != WAIT_OBJECT_0)
//Print error message and exit (-1)

//close handles
CloseHandle (hEvent);
//close child thread handles
for (i=0; i<3; i++)
CloseHandle (hThread[i]);

//end of main function

/************
* function foo
*************/

DWORD WINAPI foo (LPVOID num)
{
for( j = 0; j<3; j++)
{
//wait for single object
DWORD dwRes = WaitForSingleObject (hEvent, INFINITE);
If (dwRes == WAIT_OBJECT_0)
//print wait for set event succeeded
else
//print error
// do something
}
return 0;
}


我们邀请您在本页 发表评论 (不受客服控制),或直接向我们的支持中心 提问.