重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

こんにちは。
VC++2008Exressを使用して、以下のようなプログラムを作成したいと思います。
初心者で、どうやって作成すれば良いのか悩んでおります。
参考になるものなどありましたら、ご教授ください。

Windowsアプリケーション Win32API
メッセージループ内でWaitForSingleObjectなどのイベントを待機する関数を使用して
イベントを待つようにしたいのですが
メッセージループ内でメッセージも待機できイベントも待機できるような方法はないでしょうか?

今のところ、実現はしておりませんが検討しているのは
メッセージ待機用のスレッドを作成して、GetMessageで待機して
メッセージがきたら、SetEvent関数でメインのメッセージループ内の
WaitForSingleObjectを返す。
また、別のメッセージ以外のイベントを監視するスレッドを作成して
WaitForSingleObjectで監視してイベントが来たら、さきと同じイベントを
SetEvent関数を使用しメインのメッセージループ内のWaitForSingleObjectを返す。

という感じでメッセージとイベントをメッセージループ内で監視するようにするしか
分かりません。
その他、簡単な関数で実現可能なものなどありませんでしょうか?
WaitForMultiObjectsとか、MsgWaitForMultiObjectsやら調べてみましたが、いまいち使い方が。。。。
また、スレッドは監視イベントが来るたびに終了させた方がよいのでしょうか?
それでは、またスレッド作成を繰り返すので効率悪い気がします。
無限ループで監視させた方が良いのではと思いますが、CPU資源的には・・・。

というようなことで悩んでおります。
どうか、ご教授ください。よろしくお願いします。

A 回答 (3件)

混乱させてしまいすみませんね。


いいたかったのは、ワークスレッドからデータ更新通知をどのようにメインスレッドに伝えるかです。
イベントやらメッセージではなくて、一番シンプルな WM_TIMER でチェックしたらどうかということです。
そこで画面更新すべきかどうかを判定して、必要に応じて画面更新をすればいいと思います。
描画関連はご存知のようなので。

データ処理があるようですが、もしデータ処理が重い処理であればそこもワークスレッドでやったほうがいいですね。それはまた後でいいと思いますが。

STLはご存知ですか? 知らなければ余計混乱しそうですね。データの集合には、配列やリスト構造など種類があります。それをクラスライブラリ化したものと考えてください。ただテンプレートの概念やSTLの設計思想などを知る必要があり、初心者には敷居が高いです。

勉強という意味では、手作りのほうがいいですね。リングバッファはご存知でしょうか。
ネットでサンプルを検索すればいろいろ見つかると思います。
ワークスレッドがリングバッファにデータを書き込み、メインスレッドがリングバッファからデータを読み込みます。データ処理を行うアプリケーションの基礎ですので、知らなかったら是非取り組んでみてはどうでしょう。STLはそれを楽して作るためのライブラリです。

スレッドセーフというのは
1つのオブジェクトに対して、複数のスレッドから同時にコールされたときに動作を保障することを意味します。スレッドを使ったアプリでは必須の知識です。
クリティカルセクションを使用します。
これもネットで探してみてください。
    • good
    • 0
この回答へのお礼

いろいろと回答ありがとうございました。勉強して進めていきたいと思います。また、分からないところが出ましたら質問させて頂きます。忙しい中、相手して頂きありがとうございました。

お礼日時:2011/10/06 08:46

メッセージで通知するのはやめたほうがいいですね。

ワークスレッドが100ms毎にメッセージが投げるのにたいして、メインスレッド側はGUIの処理であり、メッセージハンドラで時間がかかるかもしれません。
その場合に、メッセージがキューに溜り、いざ動き出すと同じメッセージを短時間のうちにいくつも処理することになります。

だれが表示更新タイミングを作るかという課題になりますね。
受信したデータを画面に表示するようなアプリであれば、メッセージのタイマーを使用して定期的にそれまでに受信したデータを吸出しに行くような実装でもいいかもしれないですね。シンプルな実装になります。

受信したデータについてはどうお考えですか。
STLのqueue クラスを派生して、スレッドセーフなクラスを作れば、綺麗に収まると思います。
そのクラスのオブジェクトに、ワークスレッドからはpush, メインスレッドからはpopです。

クラス化、汎用化よりも、まずはデータの流れ、目的にあった動作についての分析、設計をして、そこが固まってから、どうクラス化するかを考えていったほうがいいと思います。

この回答への補足

>だれが表示更新タイミングを作るかという課題になりますね。
これは、WM_RECVなりのメッセージを作成して、データ処理をした後で
InvalidateRect、UpdateWindowで更新かなと思ってました。
>メッセージのタイマーを使用して定期的にそれまでに受信したデータを
>吸出しに行くような実装
これはWM_TIMERを使用するってことですよね?
この場合だと、ワークスレッドがデータ受信完了したよっていうフラグを
タイマーごとにチェックするってことですよね?
この場合でも、画面更新は、WM_TIMER内でInvalidateRect、UpdateWindowか
SendMessageでWM_PAINTを送るとしか思いつきません。。。

すいません。最後のスレッドセーフなところですが、、
vectorを使うっていうことですか??
>STLのqueue クラスを派生して、スレッドセーフなクラスを作れば
ここの文章が申し訳ありませんが、1文で書かれても理解できません。
スレッドセーフという言葉はなんとなく分かりますが。。。
僕の素人的な考えではqueueクラスを派生といわれると、
queueクラスの孫クラスを作るってことになりますか?
すでにあるMicrosoftさん?が準備してあるqueueクラスをベースとして
孫を作るってことなんでしょうか??
失笑される質問かもしれませんが、そんなレベルです。申し訳ありません。
何かお勧めの参考書とかありましたら、ご教授頂ければと思います。

補足日時:2011/10/05 11:51
    • good
    • 0

メッセージと、同期オブジェクトを1つのスレッドで待機するのはセオリーから外れます。


どうしてもCPUに無駄な処理が発生してしまいます。

まず、メインスレッドがメッセージループである必要性はありますか?
GUIを処理するスレッドであればメッセージでいいかと思いますが。
その場合、ワークスレッドからの通知はメッセージにすべきです。

今の状態は、手段から目的を作ろうとしているように見えます。
目的のための手段をまず考えましょう。

メインスレッドと、ワークスレッドでそれぞれどういう処理をさせたいかを書いてもらえれば、みなさんからアドバイスが入ると思います。

二つ目の質問の「スレッドは監視イベントがくるたびに終了させたほうがよいか」についても、同様ですね。まずはどういうアプリケーションを作るかを書いてもらえますか。
スレッドの一回の実行時間がどのくらいかによっても判断が変わりますね。1秒間に10回イベントを発行させる可能性があるのなら、ワークスレッドは常駐すべきでしょうし、10分で1回程度であれば、毎回スレッドを生成しなおしたほうが余計な同期処理を考えなくていい分、設計が楽です。

このあたりはいろいろ自分で小さなプログラムで試してみるのが一番ですが。

この回答への補足

こんばんは。
回答ありがとうございます。

>まず、メインスレッドがメッセージループである必要性はありますか?
>GUIを処理するスレッドであればメッセージでいいかと思いますが。
>その場合、ワークスレッドからの通知はメッセージにすべきです。

メインスレッドはGUIにしたいです。
別スレッドでRS232Cの受信を行い、そのデータ(1024byte)を、できれば、
メッセージループではなく、イベントでメインスレッドへ通知して
メインループでデータを処理して表示するようにと考えていました。
通信の頻度的には100msecに1回程度ですが
イベントにこだわっているのは、この別スレッドというのは汎用性を
持たせたクラスで作成したいと思うからです。
このクラスを別のアプリ作成で利用する時に、メッセージループで
作成するよりはイベントの方が利用しやすいのではと思ったので
そう検討していました。

>二つ目の質問の「スレッドは監視イベントがくるたびに終了させたほうがよ
>いか」についても、同様ですね。

こちらは分かりました。100msecでイベント発生させますのでスレッドは終了させないでおくのがよさそうですね。

補足日時:2011/10/04 00:37
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!