NHN Cloud Meetup 編集部
NHN Cloudの技術ナレッジやお得なイベント情報を発信していきます
2019.11.11
13,982
新しいプロセスを作成するとき、Linuxではfork()を使用します。
fork()から親プロセスは子プロセスを生成し、子プロセスで実際に実行しようとするプログラムをexec()を通じて実行します。
子プロセスがexit()を呼び出して終了すると、親プロセスはwaitpid()を明示的に呼び出して、この子プロセスのexit値を取得する必要があります。
子プロセスがexit()を呼び出しても、親プロセスがwaitpid()で子プロセスのPIDを回収(reaping)しなかった場合、この子プロセスはゾンビ(zombie)状態になります。
$ ps -e -o pid,stat,comm | grep a.out 32499 S+ a.out 32500 Z+ a.out <defunct>
しかし、このようなゾンビプロセスはなかなか見ることができません。
通常は親プロセスがwaitpidでうまく処理するように組まれているからです。
また、このようなゾンビプロセスが生じても、親プロセスが終了すると、カーネルはこのゾンビプロセスをinit(またはSystemd)プロセスの子として取り込みます。initやSystemdは定期的にwaitpid()を用いてゾンビプロセスを回避します。
(https://en.wikipedia.org/wiki/Zombie_process 参照)
このようなことから、我々がゾンビプロセスを見ることができる状況は2つに限定されます。
ゾンビを直接見てみたい方は下のコードをご利用ください。
コンパイルして実行し、5秒後にPSで該当のバイナリ状態を見れば確認できます。
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
int main()
{
int pid;
int status;
pid = fork();
//signal(SIGCHLD, SIG_IGN);
if (pid == 0)
{
sleep(5);
printf("I will be back %d\n", getpid());
exit(0);
}
else if(pid > 0)
{
printf("Im parent %d\n", getpid());
printf("Press any key\n");
getchar();
/*
while(1)
{
printf("Im sleeping\n");
sleep(1);
}
*/
}
else
{
perror("fork error :");
}
}