クライアント(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ランキング
-
バックグラウンドのプロセスの...
-
C#でのbatファイル実行結果取得
-
別のプロセスの関数を呼び出す...
-
Visual C++からpingを実行して...
-
explorer.exeが異様にメモリを食う
-
タスクマネージャーのプロセス...
-
VBAで別プロセスのExcelのフル...
-
プロセスIDからウィンドウハ...
-
ADOでアクセスのレコードに...
-
API関数 GetExitCodeProcess
-
特定ユーザーのプロセス情報を...
-
EXE間でデータを受け渡し時のka...
-
ウィンドウのタイトルからプロ...
-
共有メモリの使い方について
-
GetModuleFileNameでエラーが出...
-
sleep関数の精度について
-
完全な乱数を生成する方法
-
VB.NET 自プログラムのプロセス...
-
execvpでのcdコマンドについて。
-
Linuxでのスレッド間メッセージ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バックグラウンドのプロセスの...
-
explorer.exeが異様にメモリを食う
-
なぜ女性は男性が忘れたことを...
-
タスクマネージャーのプロセス...
-
プロセスのアタッチ・デタッチ...
-
非表示になったエクセルは?
-
Process.Startの戻り値を後で取得
-
C#でのbatファイル実行結果取得
-
プロセスIDからウィンドウハ...
-
c言語でプロセスIDを調べたい
-
Linuxでのスレッド間メッセージ...
-
プロセスIDの取得方法について
-
ADOでアクセスのレコードに...
-
怪しいプロセス教えてください。
-
vb.netでEXCEL起動がうまくでき...
-
別のプロセスの関数を呼び出す...
-
C++のプログラムをバックグラウ...
-
Visual C++からpingを実行して...
-
VBS(WSH)で開いたIEのウィンド...
-
IISがフリーズ
おすすめ情報