2

いくつかのフォークを伴う宿題のプログラムを書いていますが、変数の共有とゾンビプロセスの処理については少しわかりません。

  1. グローバル変数がある場合、親とすべての子はそれらのグローバル変数の同じ「コピー」で動作しますか?そうでない場合、それらを(vfork?)に到達させる方法はありますか?

  2. ゾンビのプロセスが何であるかは知っていますが、それらを取り除く方法がわかりません。wait()私のプログラムは多くの一時的なプロセスをスピンオフするので、それぞれを個別に実行できるかどうかはわかりません。親プロセスが終了すると、それに関連付けられているすべてのゾンビが削除されますよね?親が子の前に終了した場合はどうなりますか?子供はゾンビが終わったときにゾンビを置き去りにしますか(これらはinit()定期的にクリアされますか)?

  3. 子プロセスの結果は実際には気にしないので、質問2を完全に回避する可能性がありますが、ゾンビをまったく残さないようにする方法はありますか?何かを見ましたsignal(SIGCHLD, SIG_IGN)が、使い方がわかりません。見つけたマンページはやや鈍感でした。

4

2 に答える 2

5

1) グローバル変数がある場合、親とすべての子はそれらのグローバル変数の同じ「コピー」で動作しますか? そうでない場合、それらを (vfork?) にする方法はありますか?

スタックは完全にコピーされます。コピーされ、共有されません。したがって、親と子が通信したい場合は、ソケットまたは共有メモリを使用する必要があります。またはスレッド。

質問 2 をスキップ:

3)子プロセスの結果を実際には気にしないので、質問2を完全に回避する可能性があります。ゾンビをまったく残さないようにする方法はありますか?私は signal(SIGCHLD, SIG_IGN) について何かを見ましたが、それを使用する方法がわかりません。

POSIX では、プログラムに特別なシグナルを使用できます。たとえば、ctrl+c は割り込みシグナル (SIGINT) を送信し、SIGINT ハンドラーを定義していない場合はプログラムを終了します。

SIGCHLD は、子プロセスが終了した場合にプログラムが受け取るシグナルです。デフォルトでは無視されます。では、ちょっとしたシグナル ハンドラを自分で作成してみませんか? シグナル ハンドラーは、引数として int のみを持つ void 関数です。

void cleanup_child(int signal) {
    wait();
}

次に、メイン関数の最初にシグナル ハンドラーを登録し、完了です。

int main(...){
    signal(SIGCHLD,cleanup_child);
    ...

すべてのゾンビが自動的に駆除されるようになりました。シグナルは現在のプログラムを中断し、特定のシグナル ハンドラを呼び出し、プログラムを再開することに注意してください。

于 2012-02-12T20:20:39.207 に答える
1

1) 2 つのプロセスはグローバル変数を共有しません。

2) を使用waitid (2)すると役立つ場合があります。男を見てください。

親プロセスが子の前に終了した場合、子は新しい親 (PID=1 のプロセス) を取得しますinit。子供がゾンビの場合、initこの問題は自動的に解決されます。

于 2012-02-12T20:15:07.020 に答える