
こんにちは。
VC++2008Exressを使用して、以下のようなプログラムを作成したいと思います。
初心者で、どうやって作成すれば良いのか悩んでおります。
参考になるものなどありましたら、ご教授ください。
Windowsアプリケーション Win32API
メッセージループ内でWaitForSingleObjectなどのイベントを待機する関数を使用して
イベントを待つようにしたいのですが
メッセージループ内でメッセージも待機できイベントも待機できるような方法はないでしょうか?
今のところ、実現はしておりませんが検討しているのは
メッセージ待機用のスレッドを作成して、GetMessageで待機して
メッセージがきたら、SetEvent関数でメインのメッセージループ内の
WaitForSingleObjectを返す。
また、別のメッセージ以外のイベントを監視するスレッドを作成して
WaitForSingleObjectで監視してイベントが来たら、さきと同じイベントを
SetEvent関数を使用しメインのメッセージループ内のWaitForSingleObjectを返す。
という感じでメッセージとイベントをメッセージループ内で監視するようにするしか
分かりません。
その他、簡単な関数で実現可能なものなどありませんでしょうか?
WaitForMultiObjectsとか、MsgWaitForMultiObjectsやら調べてみましたが、いまいち使い方が。。。。
また、スレッドは監視イベントが来るたびに終了させた方がよいのでしょうか?
それでは、またスレッド作成を繰り返すので効率悪い気がします。
無限ループで監視させた方が良いのではと思いますが、CPU資源的には・・・。
というようなことで悩んでおります。
どうか、ご教授ください。よろしくお願いします。
No.3ベストアンサー
- 回答日時:
混乱させてしまいすみませんね。
いいたかったのは、ワークスレッドからデータ更新通知をどのようにメインスレッドに伝えるかです。
イベントやらメッセージではなくて、一番シンプルな WM_TIMER でチェックしたらどうかということです。
そこで画面更新すべきかどうかを判定して、必要に応じて画面更新をすればいいと思います。
描画関連はご存知のようなので。
データ処理があるようですが、もしデータ処理が重い処理であればそこもワークスレッドでやったほうがいいですね。それはまた後でいいと思いますが。
STLはご存知ですか? 知らなければ余計混乱しそうですね。データの集合には、配列やリスト構造など種類があります。それをクラスライブラリ化したものと考えてください。ただテンプレートの概念やSTLの設計思想などを知る必要があり、初心者には敷居が高いです。
勉強という意味では、手作りのほうがいいですね。リングバッファはご存知でしょうか。
ネットでサンプルを検索すればいろいろ見つかると思います。
ワークスレッドがリングバッファにデータを書き込み、メインスレッドがリングバッファからデータを読み込みます。データ処理を行うアプリケーションの基礎ですので、知らなかったら是非取り組んでみてはどうでしょう。STLはそれを楽して作るためのライブラリです。
スレッドセーフというのは
1つのオブジェクトに対して、複数のスレッドから同時にコールされたときに動作を保障することを意味します。スレッドを使ったアプリでは必須の知識です。
クリティカルセクションを使用します。
これもネットで探してみてください。
いろいろと回答ありがとうございました。勉強して進めていきたいと思います。また、分からないところが出ましたら質問させて頂きます。忙しい中、相手して頂きありがとうございました。
No.2
- 回答日時:
メッセージで通知するのはやめたほうがいいですね。
ワークスレッドが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クラスをベースとして
孫を作るってことなんでしょうか??
失笑される質問かもしれませんが、そんなレベルです。申し訳ありません。
何かお勧めの参考書とかありましたら、ご教授頂ければと思います。
No.1
- 回答日時:
メッセージと、同期オブジェクトを1つのスレッドで待機するのはセオリーから外れます。
どうしてもCPUに無駄な処理が発生してしまいます。
まず、メインスレッドがメッセージループである必要性はありますか?
GUIを処理するスレッドであればメッセージでいいかと思いますが。
その場合、ワークスレッドからの通知はメッセージにすべきです。
今の状態は、手段から目的を作ろうとしているように見えます。
目的のための手段をまず考えましょう。
メインスレッドと、ワークスレッドでそれぞれどういう処理をさせたいかを書いてもらえれば、みなさんからアドバイスが入ると思います。
二つ目の質問の「スレッドは監視イベントがくるたびに終了させたほうがよいか」についても、同様ですね。まずはどういうアプリケーションを作るかを書いてもらえますか。
スレッドの一回の実行時間がどのくらいかによっても判断が変わりますね。1秒間に10回イベントを発行させる可能性があるのなら、ワークスレッドは常駐すべきでしょうし、10分で1回程度であれば、毎回スレッドを生成しなおしたほうが余計な同期処理を考えなくていい分、設計が楽です。
このあたりはいろいろ自分で小さなプログラムで試してみるのが一番ですが。
この回答への補足
こんばんは。
回答ありがとうございます。
>まず、メインスレッドがメッセージループである必要性はありますか?
>GUIを処理するスレッドであればメッセージでいいかと思いますが。
>その場合、ワークスレッドからの通知はメッセージにすべきです。
メインスレッドはGUIにしたいです。
別スレッドでRS232Cの受信を行い、そのデータ(1024byte)を、できれば、
メッセージループではなく、イベントでメインスレッドへ通知して
メインループでデータを処理して表示するようにと考えていました。
通信の頻度的には100msecに1回程度ですが
イベントにこだわっているのは、この別スレッドというのは汎用性を
持たせたクラスで作成したいと思うからです。
このクラスを別のアプリ作成で利用する時に、メッセージループで
作成するよりはイベントの方が利用しやすいのではと思ったので
そう検討していました。
>二つ目の質問の「スレッドは監視イベントがくるたびに終了させたほうがよ
>いか」についても、同様ですね。
こちらは分かりました。100msecでイベント発生させますのでスレッドは終了させないでおくのがよさそうですね。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- PHP htmlspecialcharsが機能していないです。 バグですか? 1 2022/04/05 01:22
- ノートパソコン Windows11搭載パソコン 新規購入にあたって 4 2022/11/09 18:11
- 政治 政治に関する疑問を色々ぶつけられるイベントについて 1 2022/12/13 15:43
- PHP if(preg_match("/[^0-9]/",$gu_d)){意味を教えてください。 1 2022/05/06 05:37
- 固定電話・IP電話・FAX 固定電話・勝手に、頻繁にFAXフィルムが巻き上げられフィルムが無駄になる。 2 2022/08/30 10:49
- JavaScript カラーミーショップのsectionループ内で、[引数][戻り値]ありの関数的な処理を行いたいです。 1 2022/05/07 19:39
- その他(アウトドア) 露天(かき氷)、発電機(ポータブル電源)の容量 イベントでかき氷屋の露天をする事になりましたが、野外 3 2023/04/17 21:08
- Outlook(アウトルック) outlookの返信メールで、メッセージ/フォント機能が働かない。 1 2022/04/07 13:03
- MySQL MySQLのテーブル作成で 自信がありません。 2 2022/08/28 05:35
- その他(プログラミング・Web制作) 機械語に詳しい方 2 2022/07/10 12:06
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
スレッドの監視方法について
-
PHP5のスレッドについて、
-
pthreadの使い方
-
スレッドの終了はどうやるんで...
-
Linuxでスレッド優先度って変え...
-
同一スレッドで、ロックをかけ...
-
MFC モーダルダイアログに動的...
-
メインスレッドのPostMessageと...
-
Windows上で、シグナル(SIGTERM...
-
.netアプリへのSendMessageでフ...
-
別スレッドからのフォームのテ...
-
スレッド一覧の取得
-
スレッドの名前の取得について
-
VC++スレッドの正しい終了のさ...
-
_beginthreadとPostThreadMessa...
-
自作クラスのイベントを外部ハ...
-
スレッドの安全な終了のさせ方
-
スレッドの終了の仕方
-
スレッドを効率的に使うとは?
-
マルチスレッドプログラム
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
スレッドの監視方法について
-
VC++スレッドの正しい終了のさ...
-
スレッドにて同一メモリの書き...
-
スレッドの終了の仕方
-
VB2005 シリアル通信のClose処理
-
WaitForSingleObjectの使い方に...
-
別スレッドのデータを受信できない
-
同一スレッドで、ロックをかけ...
-
CWnd::OnTimerのスレッドの取得
-
スレッドの安全な終了のさせ方
-
メインダイアログが最背面に表...
-
スレッド一覧の取得
-
Windows上で、シグナル(SIGTERM...
-
C言語で一定時間待機後、再実行
-
C#でスレッド実行中のイベント...
-
複数スレッドを動作させるのに...
-
.netアプリへのSendMessageでフ...
-
DirectX LPDIRECT3DDEVICE9のマ...
-
スレッド内でコントロールやWin...
-
DirectX 11のConsntanBuffer
おすすめ情報