クライアント(Windows)とサーバ(Unix)の通信アプリを作っています。
ソケットプログラムはクライアント側はVBで、サーバ側はCです。
データの送受信はうまくいきました。ところが、データを送信後サーバ側でデータを解析し、その結果を印刷するというしくみなのですがこの全処理が終わらないとクライアント側に送信終了のイベントが発生しません。
クライアント側がデータを送信したら、あとはサーバ側で処理をする、というふうにしたいのです。
そこでサーバ側のアプリは次のような構造になっています。
App1(ソケットアプリ)
exec でApp2 を起動 App2(データの送受信)
wait あり exec でApp3 を起動 App3(データ解析)
wait なし exec でApp4,App5 を起動
wait あり、sleep あり
App3以降で時間がとてもかかります。wait,sleep が入っているからですが、これはデータ解析する上で必要な手順です。データの送受信はApp2までで終わっているので、App3のプロセスを発行したらソケット切断にしたいのですが、App3が全て終わるまで待ってしまいます。
起動のさせ方でなんとかならないものかと思うのですが、どうぞアドバイスを宜しくお願いいたします。
No.1ベストアンサー
- 回答日時:
全体の構造が詳しく分からないので、ひょっとすると見当違いかも知れませんが、私の経験から幾つかのアドバイスをしましょう。
まず、親プロセスでwaitを使わないときには、子プロセスからの終了シグナルを処理しない、と明言しておかないといけません。子プロセスは終了するときに、親プロセスがシグナルを受け取ったかどうかをチェックしていて、受け取るまでゾンビプロセスになって、残っていきます。もちろん親プロセスが終了してしまうと、このプロセスも消えますが.....。終了シグナルを処理しない、という名言は、Solaris では、sigignore(SIGCHLD) というのがあります。他のUNIX系でも似たようなシステムコールあるいは、シグナルが存在するでしょう。
ただ、上記の問題は直接はクライアント側のロックにはつながらないかも知れません。ただ、以下の理由と組み合わさると、ファイルディスクリプタがゾンビに残り続けるということも起こらないやもしれません。
もう一つ、fork, execをやる場合、ソケットなど、様々なファイルディスクリプタの情報が、子プロセスに受け継がれます。受け継がれたあと、親プロセスでソケットを閉じたとしても、子プロセスに残っているので、クライアントではソケットはつながりっぱなしです。子プロセスから孫プロセスへ受け継いでいけば、どんどんディスクリプタはコピーされるわけで、問題は波及していきます。これを解決するのは単純で、forkのあと、子プロセス側で、必要のないファイルディスクリプタは閉じます。そのあとexecするという処理が必要です。
この回答への補足
今日仕事先でアドバイスしていただいたことを試してみました。
1.sigignore(SIGCHLD) の記述
2.子プロセスでソケットディスクリプタを閉じてexitする
サーバ側では、データの受信(子プロセス)のあとデータ解析と印刷は孫プロセスがやっています。データを受信してしまったらソケットを切断してもいいので、子プロセスの終了時にソケットディスクリプタを閉じました。結果は残念ながらこれまでと同じくデータ解析等処理の終了までクライアントに切断のイベントは発生しません。ファイルのopen・closeは各プロセス内でやっているので他に閉じるディスクリプタは見当たりませんし。
申し訳ありませんが、まだほかに思い当たることがありましたらお教えください。
よろしくお願いいたします。
ありがとうございます。
もともとこのソフトは、クライアント(MS-DOS)とサーバ(UNIX)で作られていたものを、できるだけサーバのソフトをそのまま生かす形でクライアントのソフトだけ作り変えています。サーバ側のソフトは私が作ったものではなく、UNIXシステムプログラミングに不慣れなこともあり、fork・exec・wait・signalのあたりを今勉強しているところです。
「fork, execをやる場合、ソケットなど、様々なファイルディスクリプタの情報が、子プロセスに受け継がれます。受け継がれたあと、親プロセスでソケットを閉じたとしても、子プロセスに残っているので、クライアントではソケットはつながりっぱなしです。」というのはまさにその通りですね。子プロセス・孫プロセスで次々とディスクリプタはコピーされるのですね。ここを見直してみます。
本当に詳しいアドバイスをしていただきありがとうございます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- iCloud バックアップが完了したあと、機種変更前のスマホ、リセットしていい?? 1 2023/02/07 14:44
- 写真・ビデオ チャットアプリと写真データ漏洩 プライバシーについて 1 2023/06/19 20:59
- Android(アンドロイド) Androidスマホのデータ移行が終わらない 1 2023/08/04 17:25
- 写真・ビデオ チャットアプリと写真データ 漏洩やプライバシーについて 1 2023/06/19 03:28
- その他(IT・Webサービス) チャットアプリと写真データ 漏洩やプライバシーについて 6 2023/06/19 06:04
- 写真・ビデオ スマホアプリ 写真データへのアクセスについて 情報漏洩 2 2023/06/22 23:00
- iPad iPadの初期設定がわからない 2 2022/12/15 12:48
- iPad iPadの初期設定で appとデータのところで iPadを初めて購入したがiPhoneは持っていて 5 2023/01/18 21:36
- C言語・C++・C# TCP/IP通信時のサーバーからの受信 2 2022/11/23 09:11
- ネットワーク ニフティメールのiPhoneとWin PCでの運用 1 2023/03/30 11:19
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
タスクマネージャーのプロセス...
-
バックグラウンドのプロセスの...
-
起動中の他のプログラム(orプ...
-
CreateObjectで作成したExcelの...
-
プロセスのアタッチ・デタッチ...
-
C#でのbatファイル実行結果取得
-
Windowsでのfork方法
-
ロードアベレージが高いのです...
-
explorer.exeが異様にメモリを食う
-
シェルで親プロセス終了時に子...
-
非表示になったエクセルは?
-
他のEXEが起動しているかの確認
-
警告『 別のプロセスで使用され...
-
VB6.0 SHELLで起動...
-
VBSからbat実行(WMI)して戻り値...
-
OSPFでプロセスを分ける意義に...
-
SendMessageが失敗するときがある
-
execvpでのcdコマンドについて。
-
起動中のEXCELファイル(EXCEL...
-
API関数 GetExitCodeProcess
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バックグラウンドのプロセスの...
-
explorer.exeが異様にメモリを食う
-
タスクマネージャーのプロセス...
-
C#でのbatファイル実行結果取得
-
プロセスのアタッチ・デタッチ...
-
VB6.0 SHELLで起動...
-
プロセスIDからウィンドウハ...
-
Process.Startの戻り値を後で取得
-
ウィンドウのタイトルからプロ...
-
他のEXEが起動しているかの確認
-
ADOでアクセスのレコードに...
-
怪しいプロセス教えてください。
-
別のプロセスの関数を呼び出す...
-
C++のプログラムをバックグラウ...
-
Linuxでのスレッド間メッセージ...
-
C++でシェルを起動
-
プロセスIDの取得方法について
-
OSPFでプロセスを分ける意義に...
-
非表示になったエクセルは?
-
Windowsでのfork方法
おすすめ情報