WaitForMultipleObjectのイベント処理について - イベントの取りこぼし問題と対応方法

このQ&Aのポイント
  • WaitForMultipeObjects関数で待機している場合、引数で指定している複数のイベントオブジェクトがほぼ同時にシグナル化した場合、イベントの取りこぼしが発生する可能性があります。
  • 具体的な例を挙げると、スレッドAがイベントを発行し、スレッドBが複数のイベントを待機している場合、ほぼ同時にスレッドAとスレッドCからイベントが発生した場合、一部のイベントが取りこぼされる可能性があります。
  • 取りこぼしの可能性がある場合、対応方法としては、イベントを発行する順番を制御する、または待機するスレッドを複数のイベントに対応させるなどの方法があります。
回答を見る
  • ベストアンサー

WaitForMultipleObjectのイベントの処理について

はじめまして。 現在.NET 2003環境のVC++にて開発を行っています。 そこで知恵をかして頂きたいのですが、 WaitForMultipeObjects関数で待機している場合、 引数で指定している複数のイベントオブジェクトが ほぼ同時にシグナル化した場合、イベントの取りこぼし が発生する場合ってあるのでしょうか。 <例> スレッドA     スレッドB      スレッドC           for(;;){ SetEvent([0])     res = WaitFor...  SetEvent([1])             SleepEx(100, FALSE);           } ・スレッドBが複数のイベントを待機 ・スレッドA、Cがイベント発行 ・この場合、A、Cでほぼ同時にイベントが発生された場合、  (1)A(またはC)発行のイベントを取りこぼす  (2)A(またはC)発行のイベントを処理したのち、   のこりのイベントを再度処理する(for(;;)でループしている為) 取りこぼしの可能性があるとしたら、対応方法もできれば 知りたいです。 以上、よろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • rinkun
  • ベストアンサー率44% (706/1571)
回答No.1

基本的にセットされたイベントはクリアするまで保持されますから、次のWaitForMultipeObjectsで捕捉されます。だから(2)ですね。

neko1975
質問者

お礼

回答ありがとうございます。 やっぱり(2)ですか。 実際、テストプログラムでも(2)で動作してましたんで、 そうかとは思っていたんですが、開発中のプログラムでは、 イベントを取りこぼしたとしか思えない動作をしていまして。 他に原因がないかもうちょっと調べてみます。 ありがとうございます。

関連するQ&A

  • Javaにおけるイベント処理

    JFrame  SpritPanel   SpritPanel    JPanel     JButton A     JButton B     JButton C    JList A   SpritPanel    JList B    JTable C という構成で、JButton A をクリックしたらJList AにJButton A用のなんらかのリストを表示し、JButton BをクリックしたらJList BにJButton B用のなんらかのリストを表示し、・・・ と1つGUI部品で発生するイベントで1つまたは複数のGUI部品の更新処理を行いたいのですが、イベントリスナをどこに実装させて、どこに更新処理を書くかで迷います。 例えば、押されるJButton Aにイベントリスナーのメソッドを実装し、そこで処理を書く場合はJList Aをこのメソッド内から見えるようにしなけなくて、それをするためにインスタンスを渡したりするのが面倒に感じています。 様々なGUI部品やパネルで構成され、イベントが起きたら複数のGUI部品が更新が必要となるようなGUIアプリケーションを作る場合、どのようにイベントを処理させるのが王道なのでしょうか。 うまく質問できないので、質問内容に不明な点があれば補足いたします。

    • ベストアンサー
    • Java
  • CPUと同時処理の関係

    こんにちは。 CPUの同時処理について疑問に思ったので質問させてください。 例えば以下のような流れの処理をソフトか何かで同時に複数実行したとします。 (1)A→B→C (2)A→B→C (3)A→B→C (4)A→B→C 初心者ながら私の認識では同時処理できるタスク数=スレッド数だと認識していたので corei5の4コア、4スレッドのPCの場合、上記の作業は問題なく同時に処理してくれると認識していました。 しかし、ある方より「core i5はパワフルな性能なんだからクリック程度の動作なら50でも80でも処理できるよ。あとはメモリ次第だね」と言われ、疑問に思ったのですが 質問1 4スレッドのCPUであっても (1)A→B→C (2)A→B→C (3)A→B→C (4)A→B→C (5)A→B→C (6)A→B→C ・ ・ のように軽い動作であれば同時に処理できるのでしょうか? 私の認識ではスレッド以上の処理ですと、 (1)A→(5)A→B→(5)B→C→(5)C (2)A→(6)A→B→(6)B→C→(6)C (3)A→B→C (4)A→B→C このような感じになると思ってましたが・・・ 質問2 メモリが関係してくるというのは、どういうことでしょうか。 わかりやすく質問しようと長文になってしまい申し訳ありません。 よろしくお願いします

  • C言語である関数への同時アクセスについて

    たとえば int function() {   int value = rand(); //ランダムな数を取得   for ( int i = 0; i < 100000; i++ ) //数百ミリ秒くらい待機     ;   return value; } こんな関数を作成します。 これをマルチスレッドで同時に動かすとします。 例えばAというスレッドとBという2つのスレッドで同時に function()を呼び出すとします。 この場合Aというスレッドを呼び出してvalueに100が代入されたとして、 その後forループで待機している間に スレッドBからもfunction()が呼び出されvalueに200が代入されたとしたら、 スレッドAもスレッドBもfunctionの返す値はどっちも200になってしまうのでしょうか? 環境はWindowsXPでコンパイラはVisual Studio2005または2008を想定していますが、 一般的なCやC++の仕様ではこの場合の挙動はどうなるのでしょう?

  • CSocket通信での待機処理について

    VC++2008にて、サーバとクライアントPCにて、相互通信を行うプログラムを作成しています。 クライアントは、CSocketを利用しマルチスレッドにて通信を行っています。 thread_start→マルチスレッド作成→ CSocket::Sendでサーバへメッセージ送信→ CSocket::OnReceiveでサーバのメッセージ受信→ サーバメッセージから処理実行と言った流れです。 通常の処理は、この流れで問題ないのですが、 ある処理の場合、thread_startをforループで数回繰り返す 処理を行っています。 この時、データにタイムラグが出てしまうため、 thread_startから処理実行までの一連の流れが終了するまで、 次のthread_startは呼ばれずに待機させたいのですが、 どのようにすれば良いのかが分かりません。 Sendを呼んだタイミングで、 WaitForSingleObjectでスレッドのハンドルを渡したり、 CreateEventでイベントハンドルを渡したりしてみたのですが、 WaitForSingleObjectを呼ぶと、OnReceiveで受信する前で 止まってしまうため、そのままフリーズ状態になってしまいます。 どのタイミングでWaitFor~を呼ぶべきなのか、 もしくは、何か別の手段があるのでしょうか?

  • Access イベント制御

    Access2000+BVのフォームです。 プログラムの中でイベント発生を制御できませんか? 今困っているのは、フォームを開いている時にいろいろな処理をさせてます(処理A)。 その中にフィールドのSetFocusがあります。 すると、「レコード移動時」(処理B)と「フォーカス取得時」(処理C) のイベントが発生してそちらにとんでいきます。 ブレークポイントを置いて調べたら、処理Aの途中で処理Bに行ったり、処理Cに行ったり。 戻ってきたら処理Aの続きをしてくれるといいのですが、特にデータ量が多い時には、処理Aを頭からもう一度はじめたりします。 そしたら、また処理Bと処理Cに行ったりしてしまいます。 処理BとCに「旗」を置いて処理Aの途中だったら、なにもせず戻るようにしてますが、行き来しているうちに「旗」自体も白旗を上げてしまいます。 そこでプログラムのなかで、「 OnCurrent_Event = false 」「OnEnter_Event = true 」なんて感じでイベントが発生してもその処理に行かなくする方法はないですか? 意味が通じたでしょうか?よろしくお願いします。

  • シリアル受信の取りこぼし

    C++で作成したシリアルの受信処理について 1.受信イベントを検知 2.ReadFileでデータ読み取り 3.データ解析 の動作をスレッドの中で行うようにしているのですが 大量のデータを受け取る時に、データの取りこぼしが発生します。 取りこぼしを防ぐ処理方法や設定などはないでしょうか

  • C# イベント処理

    C#初心者ですが、イベント処理で困っています。VB6ではフィールドにてEventを宣言し、RaiseEventでイベントを発行し、WithEventsを使って他クラスでそのイベントを受け取る事ができますが、C#でどうしたら良いかわかりません。デリゲートとイベントについて理解が出来ていないので、簡単な参考例で教えて頂けないでしょうか?

  • C#でスレッド実行中のイベントについて

    メインフォームの「処理開始ボタン」をクリックすると別スレッドが起動して、そのスレッド中で重たい処理をさせ、処理中に「中断ボタン」をクリックすると中断してアイドル状態に戻る様なプログラムについてですが、 先ず、Invokeを使わずに直接スレッドを起動すると期待通りの動作となり、Thread.Sleep()中でもボタンクリックのイベントが発生します。 しかし、Invokeとデリゲートを使ったスレッドを起動させるとスレッドの処理が終了するまでイベントが発生せず、行ったきり状態になってしまいます。 処理ループ内にAplication.DoEvent()を入れるとイベントが発生する様になりますが、Thread.Sleep()中はフリーズ状態となります。 Invokeを使ったスレッドでも、Invokeを使わない場合と同じ動作をさせる方法があれば教えて頂けないでしょうか。 どうぞ宜しくお願いします。

  • VC++ 2005 MFC ボタンの無効化

    VC++ 2005 MFC ボタンの無効化 現在スレッドを使ったプログラムを作成しています。 あるボタンを押すと、 親スレッド 1、RS232C受信スレッドを作成 2、RS232Cにデータを送信 3、WaitSingleObjectでイベント待ち 4、受信状態に応じた処理 子スレッド 1、サムチェック等確認して、受信が完了すれば   受信データを格納してCEventのSetEventを発行 というような処理の部分があるのですが、待っている間にウィンドウ内にある ボタンが押せてしまいます。厳密には、イベント待ちを抜けた時点で待っている 間に押せてしまったボタンの処理が走ってしまうのですが。 EnableWindow(FALSE)をやっても駄目でした。 何かいい方法がありませんか??すいませんがよろしくお願いします。

  • イベントの取りこぼしについて

    教えて下さい。 VBで構築したアプリケーションにおいて、無限ループ内で処理を判断し、実行するようなプログラム構築にしています。この無限ループ内に「DoEvents」をセットしています。これによりOSに溜まっている、各イベントを処理していると思うのですが、処理するイベントに取りこぼしは発生しないのでしょうか? 現在、A/Dボードを実装しており、2ms周期でVBのイベントが発生するようなソフトになっています。「DoEvents」実行時に、OS側が処理に要する時間は、キューに溜まっているイベント数×1回のイベント処理時間で単純に導けるものでしょうか? また、CPUのスペックを2倍にすると、単純に処理時間は半分と計算できるものでしょうか?

専門家に質問してみよう