
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で質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
VC++スレッドの正しい終了のさせかた
C言語・C++・C#
-
スレッド処理からダイアログを表示するには?
C言語・C++・C#
-
PostMessageの連続送信
C言語・C++・C#
-
-
4
CStringからchar*への型変換について教えてください。
C言語・C++・C#
-
5
ボタンの表示の色、フォントを変更したい
C言語・C++・C#
-
6
[VC++] AfxBeginThreadで生成したスレッドの監視方法について
その他(プログラミング・Web制作)
-
7
別スレッドからメインダイアログのコントロールにアクセスする方法
C言語・C++・C#
-
8
画面リサイズ時のちらつきをなくす方法
C言語・C++・C#
-
9
ボタンの配置を変更したい
C言語・C++・C#
-
10
VC++でコントロールの境界線を描画する方法
C言語・C++・C#
-
11
DWORDの実際の型は何でしょうか
C言語・C++・C#
-
12
ボタンのオーナードローについて
C言語・C++・C#
-
13
MFC モードレスDlgについて
C言語・C++・C#
-
14
Debug Assertion Failed?
C言語・C++・C#
-
15
VC++で文字列から任意の文字を削除するにはどうしたらいいですか?
C言語・C++・C#
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
InvalidateRectがうまくいかない
-
ASP VBScriptでスクリプト実行...
-
Macターミナルで実行中のプログ...
-
powershell を使いカレントディ...
-
.NetのBackgroundWorkerクラス...
-
家電製品の電力周波数を変える機械
-
if ( a & b == b )
-
アプリケーションが終了するま...
-
C言語プログラミングで、多項式...
-
C#で通信処理。応答がない場合...
-
実行時のコマンドプロンプトを...
-
マルチスレッドのスレッド数を...
-
PIC mainループについて
-
VBA:CSVファイルの読出し手法...
-
bmp → jpeg への変換
-
.sb3のファイルを.sb2に変換す...
-
常駐するアプリケーションを初...
-
スレッドがサスペンドされてい...
-
スレッドの終了を知りたい(Wind...
-
マンセル⇔XYZ,RGB変換式或いは...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBSの処理中一旦処理を止めて再...
-
メッセージボックスのボタン名変更
-
ACCESS側からEXCELの書式を設定...
-
VBSで応答不要のメッセージボッ...
-
PostMessageの連続送信
-
エクセルVBAでクリップボード内...
-
VBA、UserFormを前面に出力して...
-
ファンクションキーのキャンセ...
-
Application.ScreenUpdating=Fa...
-
【MFC】イベントの無効化について
-
VBA kernel32 の意味
-
マウスのクリックを無視したい
-
ループを使わずに、特定時間に...
-
Excel VBA 自動的に閉じるMsgBox
-
「キャンセル」ボタン付きの処...
-
シャットダウン時のExcel強制終...
-
OSシャットダウン時の常駐アプ...
-
VB.NETで数秒間msgboxの...
-
VB6 コマンドボタン クリック...
-
Excel VBA 実行中に一瞬フリー...
おすすめ情報