
この例を考えてみましょう -
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
pid_t pid = fork();
if (pid > 0)
{
printf("Child pid is %d\n", (int)pid);
sleep(10);
system("ps -ef | grep defunct | grep -v grep");
}
return 0;
}
この例では、子プロセスは親プロセスが終了するまでゾンビのままです。どのプロセスからも収集されず、このゾンビプロセスをどのようにクリーンアップしますか?
$ ./a.out
Child pid is 32029
32029 32028 0 05:40 pts/0 00:00:00 [a.out] <defunct>
$ ps -p 32029
PID TTY TIME CMD
答え1
親プロセスが終了すると、子プロセスはそれを待ってプロセステーブルをクリーンアップするinit(pid = 1)によって継承されます。
答え2
ゾンビプロセスのポイントは、プロセスのパフォーマンスデータを保持するためにカーネルデータ構造にプレースホルダを残すことです。
親プロセスがwait(2)を呼び出すと、親プロセスはパフォーマンスデータを収集し、カーネルはデータ構造を解放します。
データをインポートする前に親が終了すると、パフォーマンスデータは適切な場合は親の独自のパフォーマンスデータにマージされ、親の親から取得されます。
さらに、親プロセスによって終了した子プロセスはプロセス1(しばしば「init」と呼ばれる)によって継承され、プロセス1はwait(2)を使用して残りのデータを収集し、カーネルがデータ構造を解放できるようにします。 。