
No.2ベストアンサー
- 回答日時:
ワーカースレッド(以下WS)でもユーザーインターフェイススレッド(以下UI)でも
スレッドはスレッドでMSが便宜上分けているだけということは覚えておいたほうが
いいです。
で、本題ですが、両者の最大の違いはメッセージポンプがあるかないかです。
メッセージポンプなしがWSで、ありがUIです。ですから、作成したスレッド内で
Windowsメッセージを処理しなければならないような場合、例えばセカンダリスレッドで
ウィンドウを作成して、時刻を表示するとか、ユーザの入力を受け付けて何らかの
処理を施すとかはUIを使います。
そうではなく、アプリがある種のサーバで、クライアントからの要求に対してデータを返却
するだけの処理のような場合はWSで行います。(まあ、クライアントからの要求に対して
いちいちWSを作るか、WaitForSingleObjectなどの待機関数で無限ループにするかなど実装
はいろいろありますが)
荒っぽい書き方をすると、Windowsのようなオブジェクト指向はUIで、旧来の
コンソールアプリのような手続き型はWSだともいえます。
最初にWSとUIは便宜上分けただけといいましたが、それはどちらもスレッドの制御関数は
同じで、スレッド作成時(AfxBeginThread)の引数で条件分岐しているだけなのがその理由です。
ですから、スレッドの制御関数を調べてみるとその違いがよくわかるので、以下のソースコードを
よくみてみてください。
thrdcore.cpp内のUINT APIENTRY _AfxThreadEntry(void* pParam)が制御関数で、どちらのスレッドを
使うにしてもこの関数がスレッドの制御関数として実行されるので中身をよく吟味してください。
No.1
- 回答日時:
すいません、例を書いていたら長くなりました…。
あくまで私はこう使っている、という内容ですが…UIスレッドは、ウィンドウ制御(初期化、描画、ボタンやタイマー等のイベント)を処理するスレッド、
ワーカースレッドはウィンドウ制御と関係無く処理をさせるスレッド、と認識しています。
簡単に言うと、長時間処理をしなければならない場合や、イベントを途中で拾わないと処理できないものはワーカースレッドを生成し、通常はUIスレッドで処理をさせると考えると良いかもしれません。
(本当にいいかは判りませんが・・・)
どんな時に使うかは、こんな感じです。
私は良くダイアログウィンドウでアプリを作るのですが、長時間処理がかかるものも実装することがあります。
この長くかかる処理を、たとえばマウスの左ボタン押下(OnLButtonDown)に実装したとします。すると、ボタンを押した後、処理が終了するまで画面の再描画が行われず、ウィンドウの移動を操作してもウィンドウは動きません。(処理している最中に他アプリのウィンドウが自分のアプリより前に来て、また自分のアプリをクリックされると、再描画が行われる・・・はずですが、再描画できない、という感じです。たまにこんなアプリ見かけませんか?)
これは、UIスレッドが通知されたイベントを拾ってマウス左押下処理を呼び出して、その処理から戻ってこないためで、再描画イベント(WM_PAINTメッセージ)や移動イベント(WM_MOVE)が処理できず、処理待ちとして溜まっている(待たされている)からです。
短い処理であれば、大して問題にはならないのですが、1分2分、1時間と続くと、さすがにアプリの使用者はバグった!と思うかもしれません。
また、最悪はWindowsが無応答としてタイトルバーに(無応答)をつけてしまいます。
こんな風に、処理が長くなるケースの場合、左ボタン押下処理にはワーカースレッドの生成処理を記述してワーカースレッドを起動し、ワーカースレッドでやらせいたい処理を行わせます。すると、UIスレッドは次のイベントを処理できる様になりますので、再描画もできますし、ウィンドウの移動もできます。
ただし、他のボタンを押したりすることもできるので、その辺りは、フラグで処理できない様にするか、ボタン等のコントロールをDisableにして、クリックできない様にしたりします。
結構前ですが、ユーザーがソフトに指示を与えてどの位待てるか、という調査があったのですが、大体2~3秒ということでした。(現在もこうなのかわかりません)
これをすぎると、ユーザーは何かしらの操作を行ったり、異常だと思うんだそうです。
私は、ワーカースレッドにする1つの判断材料として、処理時間が2~3秒かかるか否かで判断しています。
他の要因でワーカースレッドに出来なかったりすることもありますが、この時間を越えるならば、大抵はワーカースレッドで処理させています。
処理が長くなるなら、進捗をプログレスバー等で示すことも必要となります。
(動いているかどうかユーザーに教えると言うことですね)
そんな時も、ワーカースレッドにしておくと、プログレスバーの描画等も問題無く動きます。
実際の実装例や具体的な時間など
丁寧に教えていただき有難うございました。
また、これからマルチスレッドプログラミングを始める物として
本当に良い勉強になりました。
貴重な情報有難うございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PHP ここでの ②if($su_d<>"")の比較演算子 を使う理由は 1 2022/03/26 02:33
- PHP htmlspecialcharsが機能していないです。 バグですか? 1 2022/04/05 01:22
- プリンタ・スキャナー Brother MFC-7460DNの一時停止解除について 1 2022/12/03 12:38
- CPU・メモリ・マザーボード インテルCPUの世代ごとのデスクトップとノートのコア数についてこれで正しいですか?(*´ω`*) 1 2023/01/07 14:44
- PHP if(preg_match("/[^0-9]/",$gu_d)){意味を教えてください。 1 2022/05/06 05:37
- グループウェア slackについて取り急ぎ教えて頂きたいことがあります 2 2022/04/08 09:05
- 固定IP Latexの初期Fontに関する質問です。 1 2023/05/23 19:17
- BTOパソコン PCの選び方 6 2022/09/11 00:16
- 統計学 統計学の問題です。どうか教えてください。 線形回帰モデルYi=β0+β1xi+ui(i=1,2,.. 5 2023/06/16 00:51
- CPU・メモリ・マザーボード CPUについて 4 2022/07/09 13:41
このQ&Aを見た人はこんなQ&Aも見ています
-
VC++スレッドの正しい終了のさせかた
C言語・C++・C#
-
CStringのFindで文字列検索を行いたいのですが
C言語・C++・C#
-
CStringからchar*への型変換について教えてください。
C言語・C++・C#
-
-
4
[VC++] AfxBeginThreadで生成したスレッドの監視方法について
その他(プログラミング・Web制作)
-
5
CStringをwchar_tに変換したい
C言語・C++・C#
-
6
MFC通信プログラムマルチスレッドで例外スロー
C言語・C++・C#
-
7
AfxBeginThread の引数について
C言語・C++・C#
-
8
std::stringからLPCWSTR型への変換
C言語・C++・C#
-
9
MFCのタイマーのつかい方を教えてください
C言語・C++・C#
-
10
ダイアログの表示位置の保存
C言語・C++・C#
-
11
スレッド処理からダイアログを表示するには?
C言語・C++・C#
-
12
デバッグ中のエラーのことで教えてください。
C言語・C++・C#
-
13
MFC モードレスDlgについて
C言語・C++・C#
-
14
CString から LPCTSTRの型に変換
C言語・C++・C#
-
15
ボタンの表示の色、フォントを変更したい
C言語・C++・C#
-
16
WaitForSingleObjectの使い方について
C言語・C++・C#
-
17
画面を強制的に再描画させる方法
C言語・C++・C#
-
18
CWnd::OnTimerのスレッドの取得
C言語・C++・C#
-
19
現在時刻をミリ秒まで取得
C言語・C++・C#
-
20
CStringの文字列検索&抜き出しについて
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Excel VBA で処理中断(DoEvents...
-
DoEvents
-
PostMessageの連続送信
-
MFCのワーカースレッドとUIスレ...
-
「キャンセル」ボタン付きの処...
-
VBA:助けてください。呼び出し...
-
MFCのメニューバーのイベント取得
-
エクセルが勝手に立ち上がる
-
ASP.NETでのメッセージ画面を出...
-
VBA kernel32 の意味
-
Timerのカウントダウンのしかた...
-
キャンセルの方法
-
[VC++] AfxBeginThreadで生成し...
-
【C#】 あるイベントから別イ...
-
ACCESS側からEXCELの書式を設定...
-
終了処理について
-
<input type="file">タグで「キ...
-
起動後直に実行するコードはど...
-
VB.NET開発(イベントプロシー...
-
ファンクションキーのキャンセ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBSの処理中一旦処理を止めて再...
-
メッセージボックスのボタン名変更
-
VBA kernel32 の意味
-
ACCESS側からEXCELの書式を設定...
-
Application.ScreenUpdating=Fa...
-
Excel VBA で処理中断(DoEvents...
-
エクセルVBAでクリップボード内...
-
VBSで応答不要のメッセージボッ...
-
VBA、UserFormを前面に出力して...
-
【C#】 あるイベントから別イ...
-
【MFC】イベントの無効化について
-
「キャンセル」ボタン付きの処...
-
シャットダウン時のExcel強制終...
-
MFCのワーカースレッドとUIスレ...
-
Excel VBA 実行中に一瞬フリー...
-
Excel(VBA)シート上のコマンド...
-
VB.NETで数秒間msgboxの...
-
サスペンド(休止やスタンバイ...
-
ループを使わずに、特定時間に...
-
起動後直に実行するコードはど...
おすすめ情報