イベントオブジェクトで同期処理

[戻る]
谷岡 2003/10/24(金) 17:05:02
こんにちは,谷岡と申します。

MSDNライブラリの「短時間でできる汎用の同期オブジェクト」という記事に,
イベントをもとに他の同期オブジェクトを作成できるということがありますが,
たとえば以下のようにすると,ResetEvent()の直前で他のスレッドが
WaitForSingleObject()を実行してもブロックはされません。

   WaitForSingleObject( event, INFINITE );
   ResetEvent( event );
   排他が必要な処理...
   SetEvent( event );

クリティカルセクションのような排他処理をイベント以外の同期オブジェクトを
使わず実現するのはどのようにしたらよいでしょうか?

単なる好奇心ですが,よろしくお願いします。

dairygoods 2003/10/24(金) 17:27:17
自動リセットにしておけばよいのでは。

WaitForSingleObject( event, INFINITE );
排他が必要な処理...
SetEvent( event );

谷岡 2003/10/24(金) 17:42:27
dairygoodsさん,ありがとうございます。

CreateEvent()の説明に,「自動リセットオブジェクトは、待機スレッドが解放
された時点で、自動的に非シグナル状態に設定されます」 とあるので,
待機していない場合は,オブジェクトの状態は変わらないのではないでしょうか?

dairygoods 2003/10/24(金) 18:18:27
>   WaitForSingleObject( event, INFINITE );
>   ResetEvent( event );

これだと、
・ResetEventする前に他のスレッドがWaitしても通り抜けてしまう。
・複数のスレッドがWaitしていたら、全て解放されてしまう。
という点が問題ですよね。

自動リセットは、この二行を同時に行うようなものです。
複数のスレッドが待っていても1つだけが解放されます。

谷岡 2003/10/24(金) 19:19:06
dairygoodsさん,ありがとうございました。

実験しましたが,自動リセットのときは
シグナル状態でWaitForSingleObject()を待機せずに
すり抜けても非シグナル状態に変わるようですね。

リファレンスマニュアルでは待機中のオブジェクトが
解放されると非シグナル状態になると書いてありますが,
WaitForSingleObject()で待機がなくても非シグナル状態
になる仕様のようです。

MSDNの日本語リファレンスしか見ていませんが,このよ
うな認識でよろしいでしょうか?

dairygoods 2003/10/24(金) 19:57:08
> 実験しましたが,自動リセットのときは
> シグナル状態でWaitForSingleObject()を待機せずに
> すり抜けても非シグナル状態に変わるようですね。

解釈の問題のような気がしますが、
この場合も、あるスレッドがWaitForSingleObject()で待機状態になり、
即座に開放され非シグナル状態になると言う事だと思います。

谷岡 2003/10/24(金) 20:24:18
[[解決]]
dairygoodsさん,了解いたしました。
念のために,関連書籍を買って詳しい仕様を調べてみます。
ありがとうございました。

古いスレッドには追加発言できません。