1

私のプロジェクトの1つで、複数auto reset eventsのスレッドと2つのスレッドを作成しました。スレッドは、次のWaitForMultipleObjectsように、実行を続行する前にいくつかのイベントを待機するために使用します。

HANDLE  hTerminateEvent = CreateEvent(...); // auto reset
HANDLE  hStateChangedEvent = CreateEvent(...); // auto reset

void thread1Func()
{
    HANDLE  handles[2] = { hTerminateEvent, hStateChangedEvent };
    WaitForMultipleObjects(2, handles, FALSE/*bWaitAll*/, INFINITE);
    ...
}

void thread2Func()
{
    HANDLE  handles[2] = { hTerminateEvent, hStateChangedEvent };
    WaitForMultipleObjects(2, handles, FALSE/*bWaitAll*/, INFINITE);
    ...
}

以前、シングルになると両方のスレッドがウェイクアップすると思っていhTerminateEventましたが、自動リセットイベントには当てはまらないようです。自動リセットイベントはランダムにウェイクアップされ、ウェイクアップするとhTerminateEventシグナルなしにリセットされます。

私の質問はこれを解決する方法です:手動リセットイベントを使用して?または、この問題を解決するための設計はありますか?ありがとう!

4

2 に答える 2

3

両方のスレッドを反応させたい場合はhTerminateEvent、手動リセットに設定する必要があります。おそらく、複数のスレッドにそれ自体を終了するように指示する信号として使用しているので、とにかく自動リセットとして設定することは意味がありません。と同じhStateChangedEventです。

CreateEvent()ドキュメントを読むと、次のように書かれています。

bManualReset [in]

このパラメーターがTRUEの場合、関数は手動リセットイベントオブジェクトを作成します。これには、ResetEvent関数を使用してイベント状態を非シグナルに設定する必要があります。このパラメーターがFALSEの場合、関数は自動リセットイベントオブジェクトを作成し、単一の待機中のスレッドが解放された後、システムはイベント状態をシグナルなしに自動的にリセットします

..。

手動リセットイベントオブジェクトの状態が通知されると、ResetEvent関数によって明示的に非通知にリセットされるまで通知されたままになります。オブジェクトの状態が通知されている間、任意の数の待機中のスレッド、またはその後に指定されたイベントオブジェクトの待機操作を開始するスレッドを解放できます

自動リセットイベントオブジェクトの状態が通知されると、単一の待機中のスレッドが解放されるまで通知されたままになります。その後、システムは自動的に状態を無信号にリセットします。待機しているスレッドがない場合、イベントオブジェクトの状態は通知されたままになります。

したがって、自動リセットイベントを使用する場合、同時に待機している複数のスレッドをウェイクアップすることはできません。

于 2012-12-12T02:59:12.123 に答える
1

イベントの代わりにセマフォを使用し、ReleaseSemaphore()を使用して、スレッドの数に等しいカウントを渡すことができます。

于 2012-12-12T02:42:55.193 に答える