
CreateThread()で作成したスレッドの終了を知りたい
(具体的には、スレッドが終了するまで待機したい)のですが、
うまくいかず困っています。WindowsAPIに関する本やネットで調べた
ところ、WaitForSingleObject()が適用できると考え、
以下のようなプログラムを作成したのですが、
元のスレッドがWaitForSingleObject()のところで
止まると同時に、CreateThread()で作成されたThread_1()も
止まってしまいます。アドバイスいただけますでしょうか。
----プログラム(該当部分)ここから----
DWORD Thread_1(LPVOID param) {
int i;
char buff[128];
/* iが99のときのみ終了してよい */
while(g_iFlg == 1)
{
for(i = 0; i < 100; i++)
{
Sleep(100);
wsprintf(buff, "%d", i);
SetDlgItemText((HWND)param, IDC_STATIC_1, buff);
}
}
ExitThread(0);
return 0;
}
BOOL CALLBACK Proc_2(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
g_iFlg = 1;
g_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Thread_1, (LPVOID)hDlg, 0, &g_dwThread);
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_BUTTON_CANCEL:
case IDCANCEL:
g_iFlg = 0;
WaitForSingleObject(g_hThread, INFINITE);
CloseHandle(g_hThread);
EndDialog(hDlg, 0);
return TRUE;
}
}
return FALSE;
}
----プログラム(該当部分)ここまで----
No.2ベストアンサー
- 回答日時:
こんにちは。
itohhといいます。このプログラムは。
(1)ウィンドウ(ダイアログ)は1つ。
(2)テキストボックスに子スレッドでカウンタを自動表示する。
(3)「キャンセル」ボタンを押下したとき、(2)の処理が終わるのを待ってから
ダイアログを終了する。
ということでしょうか?
たぶん、「キャンセル」ボタンを押下した段階で子プロセスの
>SetDlgItemText((HWND)param, IDC_STATIC_1, buff);
で止まってしまっているのでしょう。
>SetDlgItemText((HWND)param, IDC_STATIC_1, buff);
は、結局、メッセージをダイアログに投げていることになりますから(SendMessage)
他のメッセージ処理が終わるまで(この場合、「WM_COMMAND」-「IDCANCEL」)
「SetDlgItemText」のメッセージ処理が始まることはありません。
こんにちは。アドバイスありがとうございます。
> このプログラムは。
> (中略)
> ということでしょうか?
ダイアログは2つです。いわゆる「メイン」および、
「実行中」(ここではカウントしているもの)です。
そして実際には単にカウントするだけではなく、
ある処理を行うのですが、処理進捗状況を示すために、
ダイアログ上のスタティックテキストにカウンタを
表示しているのです。
とにかく、IDCANCELの処理がWaitForSingleObject()のために終了しないので、
SetDlgItemText()によるメッセージの処理がキューに止められてしまい(実行されない)、
Thread_1()も止まってしまうということですね。
う~ん、WaitForSingleObject()を1行記述するだけで
うまくいけると考えたんですが・・・残念です。
No.5
- 回答日時:
こんにちは。
itohhといいます。#4のかたの方法だとカウンタが更新表示されないのでは?
(喧嘩を売っているわけではないのですが、お気を悪くされたら、すみません。)
解決策として2つの案を。
(1)カウンタを表示するエディットボックスを別ダイアログにする。
枠なしのダイアログにエディットボックスを貼り付けて見ては如何でしょうか?
(2)WaitForSingleObjectで待機するところを別スレッドにする。
「キャンセル」ボタンを押下したとき、別スレッドを立ち上げてそちらで待機する。
WaitForSingleObjectが帰ってきたら「WM_COLSE」メッセージをPostMessageする。
といった案は如何でしょうか。
(試していないのであまり自信はないのですが...)
こんにちは。アドバイスありがとうございます。
こういう方法もありますか・・・。
No.3のところに書きました通り、メッセージの
やりとりを行うようにしたのですが、
今後のために、上記方法も覚えておこうと思います。
ありがとうございました。
~~~~~
ただ、実を言いますと、今のやり方ではちょっと不安があるのです。
メッセージをポストしたあと、実際にスレッドが終了する前に
実行がもう1つのスレッド(スレッド終了のメッセージを受ける方)に
移ってしまった場合、まだ実際にはThread_1()のスレッドが
終了していないにも関わらずスレッド終了のメッセージを受け、
CloseHandle()等のスレッド終了の処理が行われてしまう可能性が
あるということです。
とりあえず、現時点では当初の問題はクリアできたので
いったん締め切りたいと思います。
みなさまありがとうございました。
No.4
- 回答日時:
今までの回答のようにSetDlgItemTextでデッドロックが起きてしまいますね。
本来ですとPostMessage系でスレッド終了時にメッセージを送信すれば回避
できますが下記のような感じでも回避できると思います。(多分...)
1.SetDlgItemTextをSendMessageTimeoutを使用する。
(送るメッセージはWM_SETTEXT)
2.上記メッセージを送信する前に毎回g_iFlgをチェックする。
でわでわ
ご回答ありがとうございます。
なるほど、こういう方法もあるのですね。
実際にはNo.3のところに書きましたように、
メッセージをポストするように変更してしまったのですが、
上記方法も今後のために覚えておこうと思います。
ありがとうございますた。
No.3
- 回答日時:
>WaitForSingleObject()1行記述するだけで
>実現できると簡潔でよかったんですが・・・
WaitForSingleObjectは、あくまでも引数に指定したオブジェクトの状態が変化するまで処理を停止する関数です。
今回の場合、ウィンドウを持つスレッド自体の動きは停止してはいけないのでWaitForSingleObjectは使えません。
”待機したい”という意味が、”プログラムを停止してスレッドの終了を待ちたい”というのでしたらWaitForSingleObjectを使うのですけどね。
アドバイスありがとうございます。
なるほど。
結局、WaitForSingleObject()で待つことをやめ、
Thread_1()のExitThread()の直前でメッセージを投げ、
そのメッセージを受けてCloseHandle()、EndDialog()を
行うようにしたら、うまくいきました。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# C++のcase文の書き方 4 2023/02/24 20:50
- C言語・C++・C# C++のcinの動作 5 2023/02/26 00:13
- Java javaでのプログラム(配列)について質問です. 2 2022/10/14 22:27
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- Visual Basic(VBA) vbaでセルに入力したときに,その横にあるセルを保護し入力不可にするマクロを作りたいです。 2 2022/04/24 20:59
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
- PHP htmlspecialcharsが機能していないです。 バグですか? 1 2022/04/05 01:22
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
MFCスレッド CriticalSection
-
スレッドにて同一メモリの書き...
-
スレッドの監視方法
-
スレッド終了を待つ間に開放さ...
-
Macターミナルで実行中のプログ...
-
CGIの記述について教えてくださ...
-
PerlScriptでMSAgentをプログラ...
-
winsockを使った通信方法
-
テキストファイルを読み込んで...
-
マイコンからプログラムを読み...
-
家電製品の電力周波数を変える機械
-
VBAの配列サイズとメモリに関して
-
ロータリーエンコーダがうまく...
-
メモリ解析の方法
-
アセンブリ言語の問題
-
MACアドレスの調べ方
-
PC-98で拡張メモリを使え...
-
プロセスIDからウィンドウハ...
-
C言語でチャットプログラミング...
-
SSL_connect(ssl)
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
スレッドの監視方法について
-
VC++スレッドの正しい終了のさ...
-
スレッドにて同一メモリの書き...
-
スレッドの終了の仕方
-
VB2005 シリアル通信のClose処理
-
WaitForSingleObjectの使い方に...
-
別スレッドのデータを受信できない
-
同一スレッドで、ロックをかけ...
-
CWnd::OnTimerのスレッドの取得
-
スレッドの安全な終了のさせ方
-
メインダイアログが最背面に表...
-
スレッド一覧の取得
-
Windows上で、シグナル(SIGTERM...
-
C言語で一定時間待機後、再実行
-
C#でスレッド実行中のイベント...
-
複数スレッドを動作させるのに...
-
.netアプリへのSendMessageでフ...
-
DirectX LPDIRECT3DDEVICE9のマ...
-
スレッド内でコントロールやWin...
-
DirectX 11のConsntanBuffer
おすすめ情報