こんにちは。
WaitForSingleObjectを使って、スレッドがシグナル状態になるまで待機するために、以下のようにコーディングしました。
WaitForSingleObject( threadHandle, INFINITE );
ところが上記だと、スレッドが正常にシグナル状態にならなかった場合に、永遠に待ち続けフリーズしてしまう可能性があること以下のサイトで知りました。
http://hitokuso.kicks-ass.org/progtips.html#1
while( ::WaitForSingleObject( threadHandle, 50 ) == WAIT_TIMEOUT )
{
MSG msg;
::GetMessage( &msg, NULL, 0, 0 );
if( !IsDialogMessage( &msg ) )// ダイアログ内の場合
{
::TranslateMessage( &msg );
::DispatchMessage( &msg );
}
}
上記のようにwhileループで回し、タイムアウトだったらメッセージを処理しているようなのですが、タイムアウト時間として50ミリ秒を指定しているので、一瞬だけ待ってすぐにメッセージ処理を継続しているような気がします。これでは、スレッドがシグナル状態になるまで待たないような気がするのですが…
まだまだ知識不足のため、見当違いな疑問を持っているのかもしれませんが、どなたかアドバイス・ご教授をお願いいたします。
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
上記のサンプルには2点間違いがあります。
1. GetMessage() 関数はなんらかしらのメッセージが届くまで制御を戻しません。そのため、スレッドが終了したのにメッセージが届かなくなるまでは処理がブロックされてしまいます。代わりにメッセージが「あれば」取りに行く PeekMessage() 関数を使用します。
2. メッセージ処理を行いながら待機する場合には WaitForSingleObject() 関数ではなく、MsgWaitForMultipleObjects() 関数を使用します。
そのため、質問にありますスレッドがシグナル状態になるまで待つようにするには、
::GetMessage( &msg, NULL, 0, 0 );
を
while( ::PeekMessage( &msg, NULL, 0, 0 ) )
に変更すればよいかと思います。
なお、2. の問題については、タイムアウト時間をより長く設定するために必要な処理ですので、気が向いたら対策していただければよいと思います。対策方法は若干複雑になりますが、以下のようになります。
::WaitForSingleObject( threadHandle, 50 )
を
::MsgWaitForMultipleObjects(1, &threadHandle, FALSE, INFINITE, QS_ALLINPUT )
に変更して、
* MsgWaitForMultipleObjects()の戻り値が 0 の場合はスレッドが終了したため、ループを抜けます。
* 戻り値が 1 の場合は、PeekMessage() 以下の処理を実行します。
* それ以外の場合には、エラーが発生していますのでエラー処理を実行してループを抜けます。
No.3
- 回答日時:
#1の方の回答の通りですが、少し補足します。
URLの説明は、スレッド中でSendMessage()を使っているとそのメッセージを受け取ってやらないとスレッドが終了しないので、スレッドを終了させるためメッセージを受け取ってやる例として質問にあるコードをあげてあるようです。
実際は、そのスレッドが何をしているかによります。
直接SendMessage()は呼んでいなくても、間接的に呼ばれる可能性もありますから、あまり単純にはこうしなくてはならないとは言えないと思います。
まあ、とりあえずは、画面の表示などの変更があれば使っていると思えばいいかなと。
WaitForSingleObject()はシグナル状態になった場合と、TIMEOUTした場合で戻り値が違います。
質問にあるソースではタイムアウトの場合にwhileループを実行しますから、
結果スレッドがシグナル状態になると戻り値が変化してwhileループを抜けるわけです。
つまり、スレッドを待っていることになります。
whileループの中は実行されてますから待っていないと言えなくもないですが、TIMEOUTさせることは待ちきれずに待つのをやめることですからね。
No.2
- 回答日時:
>永遠に待ち続けフリーズしてしまう可能性があること
それはただのプログラム上のバグです。
WaitForSingleObject(WaitForMultipleObjects)
はCPUに少ない負担で待ち状態にできるのがメリットです。
ですからシグナル状態まで必ず待たせたいのなら
INFINITEを指定してください。
WaitForSingleObject( threadHandle, 50 )
これだと50ミリ秒間隔で通過します。
>一瞬だけ待ってすぐにメッセージ処理を継続しているような気がします
コードを見るとそれを意図しているコードにしかみえません。
while( ::WaitForSingleObject( threadHandle, 50 ) == WAIT_TIMEOUT )
これだと
while(true){
Sleep(50);
(略)
}
と似たような動作になります。
シグナル状態で通過させたいなら
::WaitForSingleObject( threadHandle, 50 ) == WAIT_OBJECT_0
です。
No.1
- 回答日時:
このコードの場合、WaitForSingleObject()を一瞬で通過するのは確かですが、
同様にメッセージ処理部分も一瞬で通過しています。つまりwhile文によって、
WaitForSingleObject()→メッセージ処理→WaitForSingleObject()→メッセージ処理→・・・
というループ処理が延々繰り返されている事になります。
スレッド側がシグナル状態になれば、WaitForSingleObject()でそれを検知しますから
ループを抜けることができるわけです。
WaitForSingleObject()でINFINITEを指定した場合との違いはメッセージを処理するかどうかだけで
シグナル状態になるまで待機する事には変わりありませんから、
もしスレッド側が正常終了しなかった場合には、このコードでも無限ループします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) Excel-VBAの「しばらくお待ちください」のダイアログが自動的に閉じない 2 2023/05/24 15:31
- JavaScript javascriptで入力フォームが空欄の時にアラートによるエラーを出すコードを書いています。 2 2023/06/13 17:58
- JavaScript セレクトを全て選択されていないと、文字によるエラーメッセージを表示させるコードを調べています 2 2023/06/22 15:48
- Excel(エクセル) エクセルVBA Msgboxでの変数の活用 4 2023/07/23 08:33
- JavaScript 入力フォームの javascript で メールアドレスの正規チェックをを行い、ボタンをクリックして 2 2022/04/27 16:06
- HTML・CSS ボタンをクリックした時に、入力フォームのすぐ下部に、「入力欄が空白です」というテキストメッセージが表 1 2022/04/27 16:25
- PHP if(preg_match("/[^0-9]/",$gu_d)){意味を教えてください。 1 2022/05/06 05:37
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
- JavaScript Javascriptが機能せず原因が分からないので教えて頂きたいです 3 2023/06/04 14:50
- Visual Basic(VBA) ファイル全てを .xlsm に変更したところ、プログラムが途中で落ちてしまっています 17 2022/12/07 12:03
このQ&Aを見た人はこんなQ&Aも見ています
-
カンパ〜イ!←最初の1杯目、なに頼む?
飲み会で最初に頼む1杯、自由に頼むとしたら何を頼みますか? 最初はビールという縛りは無しにして、好きなものを飲むとしたら何を飲みたいですか。
-
あなたにとってのゴールデンタイムはいつですか?
一週間の中でもっともテンションが上がる「ゴールデンタイム」はいつですか? その逆で、一週間でもっとも落ち込むタイミングでも構いません。 よかったら教えて下さい!
-
これ何て呼びますか Part2
あなたのお住いの地域で、これ、何て呼びますか?
-
牛、豚、鶏、どれか一つ食べられなくなるとしたら?
牛肉、豚肉、鶏肉のうち、どれか一種類をこの先一生食べられなくなるとしたらどれを我慢しますか?
-
【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
【お題】 ・このサンタクロースは偽物だと気付いた理由とは?
-
CString から LPCTSTRの型に変換
C言語・C++・C#
-
CStringからchar*への型変換について教えてください。
C言語・C++・C#
-
対象のアプリケーションが終了するまで起動し続ける
C言語・C++・C#
-
-
4
VC++スレッドの正しい終了のさせかた
C言語・C++・C#
-
5
画面を強制的に再描画させる方法
C言語・C++・C#
-
6
待機関数(WaitForMultipleObjects等)について教えてください
C言語・C++・C#
-
7
ShellExecuteEx→WaitForSingleObjectで返ってこない
C言語・C++・C#
-
8
WinAPI「MsgWaitForMultipleObjectsについて」
C言語・C++・C#
-
9
スレッドの終了の仕方
C言語・C++・C#
-
10
ボタンの表示の色、フォントを変更したい
C言語・C++・C#
-
11
DWORDの実際の型は何でしょうか
C言語・C++・C#
-
12
CStringのFindで文字列検索を行いたいのですが
C言語・C++・C#
-
13
(マルチスレッド)_beginthreadexに複数の引数を渡す
C言語・C++・C#
-
14
C++言語で、構造体のコピーは可能(しても良い)のでしょうか?
C言語・C++・C#
-
15
unsigned long long 型のフォーマット指定子
C言語・C++・C#
-
16
CloseHandle()
C言語・C++・C#
-
17
CStringの文字列検索&抜き出しについて
C言語・C++・C#
-
18
EDITコントロールで入力できる文字を制限するには?
C言語・C++・C#
-
19
CStringをwchar_tに変換したい
C言語・C++・C#
-
20
_tcscpy_s(wcscpy_s)の第二引数って
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/22】このサンタクロースは偽物だと気付いた理由とは?
- ・お風呂の温度、何℃にしてますか?
- ・とっておきの「まかない飯」を教えて下さい!
- ・2024年のうちにやっておきたいこと、ここで宣言しませんか?
- ・いけず言葉しりとり
- ・土曜の昼、学校帰りの昼メシの思い出
- ・忘れられない激○○料理
- ・あなたにとってのゴールデンタイムはいつですか?
- ・とっておきの「夜食」教えて下さい
- ・これまでで一番「情けなかったとき」はいつですか?
- ・プリン+醤油=ウニみたいな組み合わせメニューを教えて!
- ・タイムマシーンがあったら、過去と未来どちらに行く?
- ・遅刻の「言い訳」選手権
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
MFC通信プログラムマルチスレッ...
-
マルチスレッドでブレイクポイ...
-
スレッドの監視方法について
-
Windows上で、シグナル(SIGTERM...
-
WaitForSingleObjectの使い方に...
-
マルチスレッド内のループについて
-
CWnd::OnTimerのスレッドの取得
-
VC++スレッドの正しい終了のさ...
-
待機関数(WaitForMultipleObjec...
-
スレッドにて同一メモリの書き...
-
スレッドの安全な終了のさせ方
-
スレッドの終了の仕方
-
C++ GUIのメッセージループ。
-
Macターミナルで実行中のプログ...
-
バックグラウンドのプロセスの...
-
C# シリアル通信でデータ受信...
-
C言語で、メモリを解放しないで...
-
「キャンセル」ボタン付きの処...
-
C#でのbatファイル実行結果取得
-
プロダクションコードとは?
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VC++スレッドの正しい終了のさ...
-
スレッドの監視方法について
-
Windows上で、シグナル(SIGTERM...
-
WaitForSingleObjectの使い方に...
-
スレッドの安全な終了のさせ方
-
スレッドの終了の仕方
-
MFC通信プログラムマルチスレッ...
-
マルチスレッドプログラミング...
-
別スレッドからメインダイアロ...
-
マルチスレッドについて
-
.NetのBackgroundWorkerクラス...
-
スレッドにて同一メモリの書き...
-
別スレッドのデータを受信できない
-
同一スレッドで、ロックをかけ...
-
マルチスレッドの同期方法
-
スレッドの終了はどうやるんで...
-
待機関数(WaitForMultipleObjec...
-
msec単位のWait Timerが作れない!
-
CWnd::OnTimerのスレッドの取得
-
_beginthreadexで生成したスレ...
おすすめ情報