介绍
的C / C程序可以使用Win32事件对象,在若干情况下,通知等待线程的事件发生。例如,文件,命名管道和通信的重叠I / O操作的设备使用一个事件对象信号完成。Win32事件
Win32事件就像一个状态机的工作和花费之间的两个国家,即它的生命,这标志着国家和无信号状态。信号状态是指一个事件,它有能力释放线程等待该事件发出信号。事件是指在无信号状态,它不会释放任何线程正在等待这一特定事件。事件有两种类型:手动重置事件和自动重置事件。手动事件有一个信号的用户设置为无信号状态,手动使用ResetEvent函数。自动自动重置事件发生对象时提出的无信号状态。
CreateEvent函数用于创建事件的线程同步对象。手动或自动重置事件选择中提到CreateEvent函数的参数初始化。等待家庭功能(WaitForSingleObject的,WaitForMultipleObjects的)用来等待一个特定的事件发生时。组对象等待事件:单个对象的信号,或者在整个事件中的线程发出信号。此功能可以创建命名和未命名的事件对象。 SetEvent的功能是用来设置事件对象的信号状态。 ResetEvent函数用于设置事件对象的非信号状态。如果函数成功,返回该事件的句柄。如果命名的事件已经是可用的,GetLastError函数返回ERROR_ALREADY_EXISTS标志。如果命名的事件已经是可用的,OpenEvent函数用于访问先前由CreateEvent函数创建事件。代码说明
下面的示例使用事件对象来演示如何子线程的信号事件告知其主线程完成。多个线程等待主线程,这是确保进一步执行之前完成所有的线程。// Create an Manual Reset Event where events must be reset
// manually to non signaled state
HANDLE hEvent1 = CreateEvent ( NULL , true , false , L"MyEvent1" );
if ( !hEvent1 ) return -1;
HANDLE hEvent2 = CreateEvent ( NULL , true , false , L"MyEvent2" );
if ( !hEvent2 ) return -1;
HANDLE hEvent3 = CreateEvent ( NULL , true , false , L"MyEvent3" );
if ( !hEvent3 ) return -1
我们创建三个事件MyEvent1,MyEvent2,MyEvent3分别。使用CreateEvent(NULL,则真,假quot; MyEventquot的;);创建一个事件。参数说明如下:第一个参数为NULL代表默认的安全属性。第二个参数是一个手动复位事件的标志。虚假意味着事件将自动重置事件,手动重置事件标志,如果是真实的。第三个参数是一个正在创建事件的状态标志。如果为false,将创建活动,在无信号状态,如果属实,该事件将被创建的信号状态。信号状态创建一个事件意味着,将没有任何调用SetEvent的(...)发布的第一个线程正在等待信号;自动重置事件的情况下。在手动复位事件的情况下,所有的线程将被释放,正在等待这个信号,除非有调用ResetEvent(...)。第四个参数是与它全球将确定事件的名称。如果上述事件具有相同的名称已经存在,那么现有的事件句柄将被打开。{C}
三个独立的线程都推出了各自的方法。这些线程函数将模拟睡在他们的执行时间为5,10,15秒,他们的任务。事件句柄保存在一个数组,所以Array_Of_Events_Handles主线程可以等待这些句柄。DWORD WINAPI ThreadFun1( LPVOID n )
{
cout<<"Thread Instantiated 1........."<<endl;
// Get the handler to the event for which we need to wait in
// this thread.
HANDLE hEvent = OpenEvent ( EVENT_ALL_ACCESS , false, L"MyEvent1" );
if ( !hEvent ) { return -1; }
Sleep ( 5000 );
ResetEvent ( hEvent );
// Signal the event
if (SetEvent ( hEvent ))
{
cout<<"Got The signal - MyEvent 1......."<<endl;
}
CloseHandle ( hEvent );
cout<<"End of the Thread 1......"<<endl;
return 0;
}
以上是一个线程函数的例子。这基本上打开已经创建的事件,并将其重置手动5秒钟后睡觉。
现在,因为我们所有的三个线程等待处理,直到它标志着'ResetEvent(的hEvent)',线程同步,主线程等待其完成之前提前执行。输出是控制台日志给你一个事件序列的感觉。
{S0的}兴趣点
"WaitForMultipleObjects的"有限等待上MAXIMUM_WAIT_OBJECTS的处理计数,这是64。如果我们需要等待比MAXIMUM_WAIT_OBJECTS处理的,我们可以创建一个单独的线程等待MAXIMUM_WAIT_OBJECTS的和然后等待这些线程完成。使用这种方法,我们可以创建MAXIMUM_WAIT_OBJECTS线程,这些每个人都可以等待MAXIMUM_WAIT_OBJECTS对象处理。 {A}。创建多线程中的一些实际情况,似乎没有无风险,有可能是一个线程同步开销。尤其是当你有太多数量的处理等,所有句柄都被认为是信号前等待线程可以继续进一步。我写我自己的分机的WaitForAllObjects解决了这个超过64把手都应该发出信号,即等待的情况下非常有用,"bWaitAll = TRUE'。{体C3}
上面的代码基本上是在一个循环的第64 WaitForMultipleObjects的处理在一个数组"把手"。事件/处理信号时,他们从'把手'阵列和阵列推余下的句柄。这种情况持续下去,直到所有的手柄正在等待他们的信号。历史11年3月11日:首次发布。11年4月11日:第一次更新 - 意见的基础上,纠正了数组来保存事件句柄。