NHN Cloud Meetup 編集部
NHN Cloudの技術ナレッジやお得なイベント情報を発信していきます
2019.11.11
13,576
新しいプロセスを作成するとき、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 :"); } }