14

fork>execプロシージャを使用して多くの子プロセスを作成したいと思います。多くのプロセスは非常に速く終了しています(2分未満で、一部はそれよりも早く)。

私の最初の問題は、スポーンプロセスをバックグラウンドに置くことです

./spawnbot > logging.txt
[CTRL+Z]
bg 1
disown

ここまでは順調ですね。これで、spawnbotのメッセージは表示されなくなり、logging.txtに直接移動します。ただし、新しい子が作成されるたびに、その子に関するすべての情報がコンソールに再び表示されます。各子を独自のパイプで開始したいと思いました。子に出力メッセージを投稿させないためのより良い方法はありますか。コンソール?それを/dev/ nullにリダイレクトする必要がありますか、それともCのフラグを使用してこれを行う必要がありますか?

第二に、すべての子供たちが実際に殺されるわけではありません。私のps-efにはたくさんのプロセスがあります。私はそれについて何ができますか?どうすればいいですか

4

2 に答える 2

22

最初に2番目の質問です!

カーネルはあなたがまだ彼らから戻り値を取得したいかもしれないと考えているので、あなたの子供は「ゾンビ」モードのままです。

子プロセスから戻り値を取得する予定がない場合は、親プロセスのSIGCHLDシグナルハンドラーをSIG_IGNに設定して、カーネルが子プロセスを自動的に取得できるようにする必要があります。

signal(SIGCHLD, SIG_IGN);

最初の質問は、実装によって異なります。

しかし、一般的に言えば、fork()の直後にclose()、0と1の古いファイル記述子を閉じてからdup2()、それらを目的の値に設定するために使用する必要があります。正しい方向。

于 2011-07-16T16:31:22.933 に答える
18

あなたの子プロセスは殺されています。無効なプロセスはゾンビプロセスとも呼ばれます。ゾンビは死んでいます!ゾンビプロセスは、プロセステーブルのエントリにすぎず、コードやメモリはありません。

プロセスが(呼び出しによって_exit、またはシグナルによって強制終了されて)停止した場合、そのプロセスはその親によって刈り取られなければなりません。プロセステーブルのエントリ以外のプロセスで使用されているすべてのリソースが表示されなくなります。親はwaitまたはを呼び出す必要がありますwaitpid。親が子プロセスの終了を通知され、子の終了ステータスを読み取る機会が得られると、プロセステーブル内の子のエントリも表示されなくなります。ゾンビが刈り取られます。

子供の死亡を通知したくない場合は、SIGCHLD信号を無視してください。これは、あなたがあなたの子供の運命を知ることに興味がなく、ゾンビが自動的に刈り取られることをカーネルに伝えます。

signal(SIGCHLD, SIG_IGN)

特定の状況での子供の死亡についてのみ通知を受けたい場合は、旗を持って電話sigactionしてください。SA_NOCLDWAIT子が死亡したときに、親がwait機能ファミリーの1つを実行している場合、子の死亡が通知され、終了ステータスが通知されます。それ以外の場合、子の終了ステータスは破棄されます。

struct sigaction sa;
sa.sa_handler = &my_sigchld_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_NOCLDWAIT;
sigaction(SIGCHLD, &sa, NULL);

出力に関しては、明示的にリダイレクトされていない限り、子は親と同じ場所に書き込みます(closeand 、、、、openまたはdup他の多くの可能性があります)。あなたの子供はおそらく標準エラーに診断メッセージを印刷しています(結局のところ、それが目的です)。

./spawnbot >logging.txt 2>&1

さらに、子供たちをターミナルから切り離したいと思われるので、ターミナルを殺した場合に子供たちがSIGHUPを受け取らないようにする必要があります。したがって、使用しますnohup

nohup ./spawnbot >logging.txt 2>&1 &
disown
于 2011-07-16T17:20:00.463 に答える