SetEvent
での複数の のトリッキーな動作を見つけました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 のシグナリング)。期待どおり、正しい「シグナル数」を取得できないことがあります。
を使用して作成された HANDLE を渡し、 を使用CreateEvent()
して HANDLE のコールバックを登録しましたRegisterWaitForSingleObjectEx()
。
この競合状態が動作の理由であると思われます。
これを克服する方法は?