- ベストアンサー
MFCのワーカースレッドとUIスレッドの使い分け
MFCのスレッドプログラミングに関して質問があります。 MFCにはワーカースレッドとUI(ユーザーインターフェース)スレッドの 2種類のスレッドがあるようですが、何が違って、どのように使い分けするのでしょうか? ワーカースレッドは、このうような処理に、 UIスレッドは、このような処理に、 と言う感じで教えて頂けると助かります。 どいぞ宜しくお願い致します。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
ワーカースレッド(以下WS)でもユーザーインターフェイススレッド(以下UI)でも スレッドはスレッドでMSが便宜上分けているだけということは覚えておいたほうが いいです。 で、本題ですが、両者の最大の違いはメッセージポンプがあるかないかです。 メッセージポンプなしがWSで、ありがUIです。ですから、作成したスレッド内で Windowsメッセージを処理しなければならないような場合、例えばセカンダリスレッドで ウィンドウを作成して、時刻を表示するとか、ユーザの入力を受け付けて何らかの 処理を施すとかはUIを使います。 そうではなく、アプリがある種のサーバで、クライアントからの要求に対してデータを返却 するだけの処理のような場合はWSで行います。(まあ、クライアントからの要求に対して いちいちWSを作るか、WaitForSingleObjectなどの待機関数で無限ループにするかなど実装 はいろいろありますが) 荒っぽい書き方をすると、Windowsのようなオブジェクト指向はUIで、旧来の コンソールアプリのような手続き型はWSだともいえます。 最初にWSとUIは便宜上分けただけといいましたが、それはどちらもスレッドの制御関数は 同じで、スレッド作成時(AfxBeginThread)の引数で条件分岐しているだけなのがその理由です。 ですから、スレッドの制御関数を調べてみるとその違いがよくわかるので、以下のソースコードを よくみてみてください。 thrdcore.cpp内のUINT APIENTRY _AfxThreadEntry(void* pParam)が制御関数で、どちらのスレッドを 使うにしてもこの関数がスレッドの制御関数として実行されるので中身をよく吟味してください。
その他の回答 (1)
- unacyo
- ベストアンサー率51% (35/68)
すいません、例を書いていたら長くなりました…。あくまで私はこう使っている、という内容ですが… UIスレッドは、ウィンドウ制御(初期化、描画、ボタンやタイマー等のイベント)を処理するスレッド、 ワーカースレッドはウィンドウ制御と関係無く処理をさせるスレッド、と認識しています。 簡単に言うと、長時間処理をしなければならない場合や、イベントを途中で拾わないと処理できないものはワーカースレッドを生成し、通常はUIスレッドで処理をさせると考えると良いかもしれません。 (本当にいいかは判りませんが・・・) どんな時に使うかは、こんな感じです。 私は良くダイアログウィンドウでアプリを作るのですが、長時間処理がかかるものも実装することがあります。 この長くかかる処理を、たとえばマウスの左ボタン押下(OnLButtonDown)に実装したとします。すると、ボタンを押した後、処理が終了するまで画面の再描画が行われず、ウィンドウの移動を操作してもウィンドウは動きません。(処理している最中に他アプリのウィンドウが自分のアプリより前に来て、また自分のアプリをクリックされると、再描画が行われる・・・はずですが、再描画できない、という感じです。たまにこんなアプリ見かけませんか?) これは、UIスレッドが通知されたイベントを拾ってマウス左押下処理を呼び出して、その処理から戻ってこないためで、再描画イベント(WM_PAINTメッセージ)や移動イベント(WM_MOVE)が処理できず、処理待ちとして溜まっている(待たされている)からです。 短い処理であれば、大して問題にはならないのですが、1分2分、1時間と続くと、さすがにアプリの使用者はバグった!と思うかもしれません。 また、最悪はWindowsが無応答としてタイトルバーに(無応答)をつけてしまいます。 こんな風に、処理が長くなるケースの場合、左ボタン押下処理にはワーカースレッドの生成処理を記述してワーカースレッドを起動し、ワーカースレッドでやらせいたい処理を行わせます。すると、UIスレッドは次のイベントを処理できる様になりますので、再描画もできますし、ウィンドウの移動もできます。 ただし、他のボタンを押したりすることもできるので、その辺りは、フラグで処理できない様にするか、ボタン等のコントロールをDisableにして、クリックできない様にしたりします。 結構前ですが、ユーザーがソフトに指示を与えてどの位待てるか、という調査があったのですが、大体2~3秒ということでした。(現在もこうなのかわかりません) これをすぎると、ユーザーは何かしらの操作を行ったり、異常だと思うんだそうです。 私は、ワーカースレッドにする1つの判断材料として、処理時間が2~3秒かかるか否かで判断しています。 他の要因でワーカースレッドに出来なかったりすることもありますが、この時間を越えるならば、大抵はワーカースレッドで処理させています。 処理が長くなるなら、進捗をプログレスバー等で示すことも必要となります。 (動いているかどうかユーザーに教えると言うことですね) そんな時も、ワーカースレッドにしておくと、プログレスバーの描画等も問題無く動きます。
お礼
実際の実装例や具体的な時間など 丁寧に教えていただき有難うございました。 また、これからマルチスレッドプログラミングを始める物として 本当に良い勉強になりました。 貴重な情報有難うございました。
お礼
マルチスレッド初心者として メッセージポンプの有無の説明が納得できました。 貴重な情報を有難うございました。