「一気に最後まで読んだ」本、教えて下さい!

VC6.0で開発しています。
今、次のような処理をどうすればよいか悩んでいます。ヒントになる回答を頂けたら幸いです。

データをやり取りする際、どのような処理を行うか命令するもの(以下、命令A)と、命令された通りのデータを送るもの(以下、送信B)、そして、AとBの通信部分を担うもの(以下、通信C)があります。

データのやりとりは、マルチスレッドで行っています。
データをやりとりするために、スレッドが通信C上で2つ起動しています。1つ目のスレッド(以下、スレッドA)は、送信Bが命令Aから送られる特定のデータ(以下、データA)を受け取れるかをどうかの信号を、命令Aに送るためのものです。2つ目のスレッド(以下、スレッドB)は、データAを通信Cが受け取り、送信Bに渡すときに起動するスレッドです。

スレッドAで、送信Bから命令Aへ、受信の準備ができたことを伝える信号が送られます。その後、命令AよりデータAが送られ、通信CでスレッドBが起動するのですが、データAを通信Cで受信したとき、スレッドAで送っている信号を初期化しなければいけません。

データAを受信したときにはスレッドBが起動しますので、スレッドAとスレッドBの間での処理ということになります。

スレッド処理について、まだまだ不勉強なのですが、よいアイディアがあれば教えてください。
よろしくお願いします。

A 回答 (4件)

アプリ毎に整理してみました。

分からないところは想像で書いています。

--命令A--
(1)「命令A→通信C」のファイルを作成。「送信Bが送信Aに対して、データの要求をしているのかを判別するデータを送信しろ」を送る。
(2)「通信C→送信B、命令A」のファイルを監視。「命令Aにデータ要求」が書き込まれるの待つ。
(3)「命令A→通信C」のファイル2を作成。「送信Bの要求データ」を作成する。
(4)「通信C→送信B、命令A」のファイルを監視。「送信Bはデータの要求をしていない」に書き換わるの待つ。
(5)(1)に戻る。

--送信B--
(1)「通信C→送信B、命令A」のファイルを監視。「送信Bが命令Aに対して、データの要求があるか」が書き込まれるのを待つ。
(2)「送信B→通信C」のファイルを作成して、「送信Bが命令Aに対して、データの要求がある」を書き込む。
(3)「通信C→送信B」のファイルが作成されるのを待つ。
(4)ファイルを読んで、データを何らかの手段で送信。
(5)(1)に戻る。

--通信C--
(1)「命令A→通信C」のファイルが作成されるを待つ。
(2)スレッド1を起動する。
(3)「送信B→通信C」のファイルが作成されるのを待つ。
(4)スレッド1に(3)に進むよう指令を出す。
(5)「送信B→通信C」のファイルを削除する。
(6)「命令A→通信C」のファイル2が作成されたことを検出。
(7)スレッド2を起動する。
(8)このあと???

・スレッド1
(1)「通信C→送信B、命令A」のファイルを作成。「送信Bが命令Aに対して、データの要求があるか」を書き込む。
(2)何らかの指令があるまで(1)を繰り返す。
(3)「通信C→送信B、命令A」のファイルを書き換え。「命令Aにデータ要求」に書き換える。
(4)何らかの指令があるまで(3)を繰り返す。
(5)「通信C→送信B、命令A」のファイルを書き換え。「送信Bはデータの要求をしていない」に書き換える。
(6)「命令A→通信C」のファイルを削除する。
(7)スレッドを終了する。

・スレッド2
(1)スレッド1に対して、指令を送り(5)に移行するように促す。
(2)「命令A→通信C」のファイル2を読み込み、「通信C→送信B」のファイルを作成する。コピー後「命令A→通信C」のファイル2は削除する。
(3)スレッドを終了する。

勘違いがあったら訂正をお願いします。

全体として問題を感じたので何点か上げます。
・ファイル作成を条件に動いている所があるが、ファイル内容が全部書き出されていないうちに動き出してしまわないか?
・必要な動作に対してやっていることが複雑である。処理の起点はなぜ送信Bの要求から始まらないのか?命令Aから始まる理由は?
・ファイルの後始末が不明確。
・スレッド1の処理で、何度もファイルを書き換える理由は?
・命令Aと送信Bが通信していれば作れそうな気がする処理で、通信Cが必要な理由が分からない。


シンプルにするとしたら、こんな感じには出来ないのでしょうか?
一応命令Aを起点にしています。スレッドがなくなってしまうので、このアプリの構成がスレッドの勉強のためだったら申し訳ない!

--命令A--
(1)送信Bにメッセージで要求がないか問い合わせる。
(2)送信Bの返事を待つ。
(3)送信要求なら、ファイルを作成する。送信不要なら(1)に戻る。
(4)送信Bにメッセージでファイルが出来たことを知らせる。
(5)送信Bの返事を待つ。
(6)(1)に戻る。

--送信B--
(1)命令Aから要求の問い合わせを待つ。
(2)命令Aにメッセージで要求の有無を送信。
(3)要求無しなら(1)に戻る。
(4)命令Aからファイルの完成メッセージが届くのを待つ。
(5)ファイルを読んで何らかの方法で送信する。
(6)ファイルを削除する。
(7)命令Aにメッセージで送信が完了したことを知らせる。
(8)(1)に戻る。

相互の通信にはWindowsAPIのPostMessageを使用する予定です。
ただし、両方のアプリにhWndが必要なので両方ともウィンドアプリである必要があります。
http://yokohama.cool.ne.jp/chokuto/urawaza/api/P …
    • good
    • 0
この回答へのお礼

返信が遅くなり申し訳ありません。

こちらの方でいろいろ考えた結果、2つのスレッドで考えるより、一つのスレッドで工夫した方がよいということになりました。

zwiさんには、私の分かりづらい説明に付き合っていただいて、ありがとうございました。

お礼日時:2007/09/10 20:45

すいません。

今読んでところなのですが。
>3.送信Bが、データを要求します。
これって、どうやって伝えていますか?
    • good
    • 0

すいません、まだ複雑でした(^^ゞ


問題なのは、データの流れがいまいち掴めないことです。
流れの順番で書いてもらえませんか?
私なりに分かっていることを想像を交えて書くと。
(1)「通信C」のスレッド「通信Cから命令Aへ」が命令Aへの通信ファイルで「送信Bがあるデータの送信を命令Aに要求している」を書き込む。
(2)「命令A」が(1)の指令を見て送信Bに送るデータファイルを作成する?
(3)「通信C」のスレッド「???」が「命令A」が作成したデータファイルを発見して「送信B」に「送信Bで送信してほしいファイルがあるよ」という意味のファイルを作成する。
(4)「送信B」は、「送信Bで送信してほしいファイルがあるよ」を見つけたら「命令A」の作ったファイルをなんらかの通信で何処かに送出する。
(5)送信処理の後始末「信号データの初期化」を行う。

って事でしょうか?(1)の前のデータ送信の起点がよく分からないのですが、どのプログラムが送信を要求しているのでしょうか?送信Bです?
印象としては、妙に複雑なことをしている気がします。もっとシンプルに作れそうな感じがするのですが、とりあえず流れが分からないとアドバイスできないので、詳細にお願いします。

この回答への補足

すいません。補足します。

1.命令Aが、命令Aから通信Cへ「送信Bが送信Aに対して、データの要求をしているのかを判別するデータを送信しろ」という命令を保存したファイルを共有ディレクトリに保存します。

2.通信Cが「1.」のファイルのデータを読み込み、送信Bが命令Aに対して、あるデータの送信を要求しているかどうかを示すデータを共有ディレクトリに保存します。「1.」で保存したファイルとは別のファイルに一定周期で上書き保存を繰り返します。この処理のために、スレッドが一つ起動します。命令Aは、このファイルを監視して、常にデータをチェックしています。

3.送信Bが、データを要求します。

4.通信Cが、送信Bがデータを要求していることを示すデータを、「2.」で保存したファイルに書き込みます。今後は、初期化されるまで、データ要求を意味するデータを保存し続けます。

5.命令Aが、データ要求を意味するデータがきたことを検出します。

6.命令Aが、要求されたデータを書き込んだファイルを、共有ディレクトリに保存します。

7.通信Cが「6.」で保存されたファイルを検出し、データを読み込み、送信Bにデータが送られます。この処理のために「2.」とは別のスレッドが一つ起動します。

8.「7.」のスレッドが起動すると同時に、「2.」で起動したスレッドでは、ファイルに保存するデータを「送信Bはデータの要求をしていない」という意味のデータを保存するようにします。つまり初期化です。

こういった感じなのですが、うまく伝わったでしょうか?
回答をよろしくお願いします。

補足日時:2007/08/25 18:49
    • good
    • 0

ごめんなさい。

説明が良くわかりません。他に返答がないのも、それが原因だと思います。命令AとかスレッドAとか???です。
どこまでが1つのプログラムなのか、関数の単位はどこまでか、A,B,C間ではデータをどうやって受け渡しているのかなど疑問がいっぱいです。そもそも信号って、signalのこと?

で、状況を整理したいと思います。
やっていることの細かい説明はおいておいて、何をやりたいかとスレッド化している理由を説明してもらえないでしょうか。
信号のデータを初期化するという言葉の意味も。

この回答への補足

すみません。質問が大雑把+内容に抜けが多すぎたようです・・・(反省)

データは、ファイルでやりとりしています。
共有のディレクトリがあり、そこにファイルが保存されます。ファイルデータを読み込むのは、命令A、通信Cと名前をつけたアプリケーションなのですが、ファイルの種類によって、どちらがデータを読み込むかが決まります。
例えば、拡張子がAAAとついたファイルなら、通信Cがディレクトリに保存し、命令Aが読み込むといった感じです。

1.スレッド化している理由
命令A、送信B,通信Cそれぞれが、一つのアプリケーションです。スレッドは通信Cで作成されます。通信Cの中の一つのクラスが共有ディレクトリにファイルが保存されたかを監視しています。ファイルが保存されると、このクラスがファイルを読み取り、そのデータに対応した関数を実行します。この実行される関数が、それぞれスレッドとなります。データごとに処理を行う必要があるので、マルチスレッドで処理しています。

2.信号データの初期化
一つのスレッド処理で、通信Cから命令Aに対して、「送信Bがあるデータの送信を命令Aに要求している」かどうかを意味するデータを、共有ディレクトリに保存し続けています。
信号データの初期化とは、送信Bが、命令Aからのデータを通信Cを経由して受け取ったあと、共有ディレクトリに保存するデータを、「現在、送信Bはデータの要求を行っていない」という意味のデータに変更するということです。

3.何をやりたいのか
「信号」データを保存し続けている処理と、データを受信する処理は別スレッドで処理されています。
「信号の初期化」を行うタイミングは命令Aが共有ディレクトリにファイルを保存し、これを通信Cが検出し、送信Bにこのファイルのデータを送るスレッドを起動したときです。
別々のスレッド間での処理になるので、このタイミングで、どう「信号」データの初期化を行えばよいかで悩んでいます。

長々と書いてしまいました。zwiさんが知りたいことに対してきちんと回答できているか不安ですが、回答をよろしくお願いします。

補足日時:2007/08/25 11:18
    • good
    • 0

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