初心者です。
よろしくお願いします。
とても重く時間の掛かる処理を色んなサイトを参考にスレッドにしてみたんですけど、書き方が悪いのか、再描写がワンテンポ遅れたり、アプリケーションを複数起動したりするとフリーズしてしまったりします。
原因はメッセージループにあるような気がしてるんですが、この書き方はおかしいですか??
どのサイトから引用したのかわからなくなってしまいました。
気付いたことなどあったら何でもいいので教えて貰えたら嬉しいです!よろしくお願いします!!
thread01に重い処理が書かれてます。
int thread_call() {
unsigned int dwThreadId[1];
HANDLE hThread[0] = (HANDLE)_beginthreadex(
NULL,
0,
( unsigned int (__stdcall*)(void*) )thread01,
NULL,
0,
&dwThreadId[0] );
MSG msg;
DWORD dwRet = WAIT_TIMEOUT;
while ( 1 ) {
dwRet = ::MsgWaitForMultipleObjects( sL, hThread, FALSE, INFINITE, QS_ALLEVENTS );
if ( dwRet == WAIT_OBJECT_0 + sL ) {
if ( ::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {
::TranslateMessage( &msg );
::DispatchMessage( &msg );
}
} else if ( dwRet >= WAIT_OBJECT_0 && dwRet < WAIT_OBJECT_0 + sL )
break;
}
CloseHandle( hThread[0] );
hThread[0] = NULL;
}
No.2ベストアンサー
- 回答日時:
>重い処理の最中でも windowのメッセージループってメッセージを受け取ってくれるんですか?
メッセージハンドラから抜けなければ受け取って(というか処理して)くれません。
今回の場合、起動したスレッドの終了を待っているのでハンドラから戻れなくなっているんですよね。
なので、時前でメッセージ処理の為のコードが入っている。と……。
# スレッドにした意味がかなりなくなりますけど。
>スレッドにしなくても大丈夫ならスレッドにしたくないです!
処理の内容次第です。
まぁ、同期処理とかちゃんとできればワーカースレッドにした方が面倒は少ないでしょう。
ワーカースレッド側でWindowsのメッセージについて考える必要はありませんし、
UIスレッドの方も処理を止められることもありませんから。
ワーカースレッドでの処理次第ですが、起動したら終了待ちしないでそのままでいいのではないかと。
# プログレスバーを表示していたり、キャンセルとかで中断させたいなら工夫が必要ですけどね。
# あと起動したスレッドの処理が終わる前に[X]ボタンで閉じられた場合…とか。
>とても重く時間の掛かる処理
がどんなモノか……に依存するってところでしょうかね。
私の場合、ワーカースレッドを中断したい場合はイベントで通知(ワーカースレッド内ではループなどのタイミングでWaitForMultipleObjects()などでイベントの状態をチェックします)して、
ワーカースレッドの終了はUIスレッドにメッセージで通知します。
# ウィンドウを閉じる…などの場合はメッセージは使えませんけど。
ウィンドウ閉じる場合はイベントでワーカースレッドに中断を通知して、ウィンドウ自体はクローズしたあとスレッドハンドルで終了を待機、その後でプロセスの終了…となりますかね。
そんなワケで…メッセージループを自前で(元々のとは別に)処理することはありませんね。
参考URL:http://rarara.cafe.coocan.jp/cgi-bin/lng/vc/vcln …
とっても難しいです!
サンプルのコピーばかりしていたせいで半分も理解できませんでした。。。
取りあえず今出来てあるものは一応動くので改良は後ほどにして、
> ワーカースレッドの終了はUIスレッドにメッセージで通知します。
この辺り、とても良さそうな感じがするので、理解できるように勉強しなおしてみたいと思います!
No.1
- 回答日時:
WindowsのGUIってコトでいい…んですよね?
thread_call()ってどこから呼ばれるんでしょう?
ボタン押下したときや、メニュー選択したときなどのメッセージハンドラ中から…でしょうか?
であれば、そのハンドラから戻るのはthread01()の処理が終わった後。
ということになります。
幸いにして時前でメッセージループを回していますので、固まることはなさそう…ですが……
あんましスレッド作った意味がなさそうですねぇ。
>再描写がワンテンポ遅れたり、アプリケーションを複数起動したりするとフリーズしてしまったりします。
複数起動については別に問題(リソースの取得で…とか)があるのではないか…と思われますが……反応が悪いのは
>dwRet = ::MsgWaitForMultipleObjects( sL, hThread, FALSE, INFINITE, QS_ALLEVENTS );
ではないですかね。
http://msdn.microsoft.com/ja-jp/library/cc429261 …
QS_ALLEVENTSということは、
>入力メッセージ、WM_TIMER メッセージ、WM_PAINT メッセージ、WM_HOTKEY メッセージ、ポストされたメッセージのいずれか
がこないとココで止まります…よね?
入力メッセージとか以外にもいろんなメッセージが流れているハズ…ですが。
ワーカースレッドを作るのであれば、_beginthreadex()でスレッド作った後は、そのまま抜けてしまってよいかと。
スレッドの終了はメッセージでGUIに通知する。という方法になるかと思われますが…。
#define WM_THREADCOMPLETE (WM_APP) とかで独自に扱うメッセージを定義して…とか。
もちろん、起動するスレッドにはそれを通知するHWNDを渡す必要がありますけど。
ハンドル保持しておいて、WM_TIMER辺りでWaitForSingleObject()でチェックする。なんてのもアリでしょうかね。タイアウトを0にしておけばオブジェクトの状態確認できますし。
# まぁ、このままでMsgWaitForMultipleObjects()ではなくWaitForSingleObjectュョでスレッドの状態を取得する。というのもありでしょう。
お返事ありがとうございます!
windowsのGUIってことでした。
thread_callはボタンを押したときに呼ばれるようになってます。
はじめはスレッドにせず作ってたんですけど、処理が終わるまでwindowを動かしたり最小化したり出来なくなってしまったのでスレッドにしてみました。
重い処理の最中でも windowのメッセージループってメッセージを受け取ってくれるんですか?
感覚で処理が終わるまでは何しても受け取ってくれないものだと思っていました。
書き方が悪いだけなんでしょうか。。
スレッドにしなくても大丈夫ならスレッドにしたくないです!
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- JavaScript javascriptで入力フォームが空欄の時にアラートによるエラーを出すコードを書いています。 2 2023/06/13 17:58
- PostgreSQL DBFluteについて質問です。 環境:PostgreSQL java8 前提:webアプリケーショ 1 2022/07/07 00:49
- C言語・C++・C# leetcode 155 minstack 1 2022/05/07 16:43
- C言語・C++・C# C言語 共用体について コマンドライン引数で値を2つ入力したときに、argv[2]の値をUNI u1 4 2022/04/25 20:34
- Excel(エクセル) Excel-VBAの「しばらくお待ちください」のダイアログが自動的に閉じない 2 2023/05/24 15:31
- JavaScript セレクトを全て選択されていないと、文字によるエラーメッセージを表示させるコードを調べています 2 2023/06/22 15:48
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
スレッドの安全な終了のさせ方
-
スレッドの監視方法について
-
WaitForSingleObjectの使い方に...
-
C++でマルチスレッドによるネッ...
-
スレッドの終了はどうやるんで...
-
C言語である関数への同時アクセ...
-
msec単位のWait Timerが作れない!
-
MFC通信プログラムマルチスレッ...
-
スレッドの終了の仕方
-
Macターミナルで実行中のプログ...
-
ショッピング
-
緯度、経度の 10進法と 60進法...
-
Mac 乗数の入力方法
-
C言語で、メモリを解放しないで...
-
MACで動く実行ファイルをWindow...
-
家電製品の電力周波数を変える機械
-
Excel-VBAのmsgBox()の不思議
-
メッセージボックスのボタン名変更
-
Excel(VBA)でSetTimer関数を使...
-
【C言語 数独】 C言語で9×9の数...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
WaitForSingleObjectの使い方に...
-
スレッドにて同一メモリの書き...
-
VC++スレッドの正しい終了のさ...
-
スレッドの監視方法について
-
Windows上で、シグナル(SIGTERM...
-
スレッドの終了の仕方
-
スレッドの安全な終了のさせ方
-
CWnd::OnTimerのスレッドの取得
-
MFC通信プログラムマルチスレッ...
-
Linuxでスレッド優先度って変え...
-
VB2005 シリアル通信のClose処理
-
.netアプリへのSendMessageでフ...
-
マルチスレッドについて
-
別スレッドからメインダイアロ...
-
スレッドの終了はどうやるんで...
-
マルチスレッドプログラミング...
-
特定のスレッドの破棄
-
別スレッドのデータを受信できない
-
msec単位のWait Timerが作れない!
-
.NetのBackgroundWorkerクラス...
おすすめ情報