4

私はこのようないくつかのコードを継承しました:

m_mutex.Lock();
ResetEvent( m_hSyncObject );
m_mutex.Unlock();

についても同じSetEvent()

この場合、これらのミューテックスは必要ですか?これらの呼び出しはそれ自体で動作しますか、それともロックを解除することで回避できますか?この関数には、以前にアトミックに作成した値のinc / decsがすでに含まれており、これらのイベントだけがロック内にあるため、可能であれば、これらのイベントを取り除くことは大きなメリットになります。

4

3 に答える 3

3

この余分なミューテックスはほぼ確実に不要です。および関数自体はResetEventSetEvent複数のスレッドから安全に呼び出すことができます

このコードが存在することを考えると、そのコードを書いた開発者は、作成したスレッドのセマンティクスを理解していなかった可能性が高いようです。そのロジックに依存するコードは、非常に疑わしいものとして扱います。長期的には、スレッドの問題についてそのコードを事前に監査することで、時間を節約できる可能性があります。

于 2012-04-09T16:19:54.250 に答える
2

警告プログラマー!

手動リセットイベントは使いにくく、イベントの設定とリセットをロックする必要がある場合があります(自動リセットイベントを使用すると、これらの問題を簡単に回避できます)。

このコードを考えてみましょう:

Worker() {
    WaitForSingleObject(hEvent);
    DoWork();
    ResetEvent(hEvent);
}

EventThread() {
    QueueWork();
    SetEvent(hEvent);
}

イベントスレッドがイベントを通知した、ワーカーがイベントをリセットするための際どいインターリーブを使用すると、待機中にワーカーがハングする可能性があります。この場合、手動リセットイベントを適切に使用するには、リセットイベントの周りのロックを取得し、イベントをリセットしてキューの状態をアトミックにチェックする必要があります。

自動リセットイベントを使用すると、アトミックにウェイクアップして、このレースを回避するイベントをリセットできます(作業が開始されたときにすでにキューを空にしていた場合は、もう1回ウェイクアップする可能性がありますが、ウェイクを見逃すことはありません)。

于 2012-05-06T17:30:06.517 に答える
1

SetEventイベントはアトミックであるため、またはの前後にミューテックスを使用する必要はありませんResetEventただし、他に何かがあり、2つをアトミックに実行する必要がある場合を除きます(たとえば、1つのイベントを設定して別のイベントをリセットする場合)。

于 2012-04-09T16:19:40.767 に答える