0

我发现多个SetEvents 与RegisterWaitForSingleObjectEx().

#include <windows.h>
#include <iostream>

using namespace System;
using namespace System::Drawing;
using namespace System::Threading;

VOID CALLBACK Callback(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
{
    String^ string = gcnew String("");

    Monitor::Enter(string->GetType());

    //wait for 2 seconds
    for(int i=1; i<=2;i++) {
        Sleep(1000);
        cout << i << " seconds \n";
    }

    Monitor::Exit(string->GetType());
}


void main()
{

     HANDLE eventhandle = CreateEvent( 
     NULL,               // default security attributes
     FALSE,              // manual-reset event
     FALSE,              // initial state is nonsignaled
     TEXT("WriteEvent")  // object name
    ); 

    //register the callback for the event
    RegisterWaitForSingleObjectEx(eventhandle, Callback, nullptr, -1, WT_EXECUTELONGFUNCTION);

    BOOL bEvented[3];
    bEvented[0] = SetEvent(eventhandle);
    //Sleep(10);
    bEvented[1] = SetEvent(eventhandle);
    //Sleep(10);
    bEvented[2] = SetEvent(eventhandle);
    cout << "event0 = " << bEvented[0] << ", event1 = " << bEvented[1] << ", event2 = " << bEvented[2] << " \n";

}

我设置了 3 次事件。所以,我希望回调被调用 3 次(如果我错了,请纠正我)。但我只收到 2 个回调。

如果我取消注释这些行//Sleep(10);,我会收到 3 个回调。这里发生了什么?

我正在使用Win7 64位

更新:

您能否举例说明如何使用信号量来实现这一目标?

实际场景:

我有一个第三方库,我必须在其中注册一个 HANDLE 以获得有关事件发生的通知。大多数时候,我都能收到通知(在 HANDLE 上发出信号)。有时,正如预期的那样,我没有得到正确的“信号数量”。

我正在传递使用创建CreateEvent()的 HANDLE 并使用RegisterWaitForSingleObjectEx().

我怀疑这种竞争条件是行为的原因。

如何克服这一点?

4

1 回答 1

1

SetEvent在已经发出信号的事件上是无操作的。您在调用 的主线程SetEvent和等待它的工作线程之间存在竞争条件(并在满足等待时自动重置它)。

SetEvent最有可能的是,当工作人员仍在运行第一个回调时,您设法调用了两次。

于 2013-09-06T19:00:14.253 回答