実際のゾンビのように、ゾンビプロセスはすでに死んでいるので、殺すことができません。
どうやって
Linux / Unixでプロセスが停止または終了すると、プロセスからのすべての情報がシステムメモリから削除され、プロセス記述子のみが残ります。プロセスは状態Z(ゾンビ)になります。彼の親プロセスはカーネルからシグナルを受け取ります。SIGCHLD
つまり、子プロセスの1つが終了するか、中断されるか、中断された後に再開されます(この場合は単に終了します)。
これで、親プロセスはwait()
syscall を実行して、子プロセスから終了ステータスおよびその他の情報を読み取る必要があります。次に、記述子がメモリから削除され、プロセスはゾンビではなくなります。
親プロセスがwait()
syscallを呼び出さない場合、ゾンビプロセス記述子はメモリ内にとどまり、脳を消耗します。通常、上記の手順は時間がかからないため、ゾンビプロセスは表示されません。
死者の夜明け
各プロセス記述子に必要なメモリは非常に少ないため、いくつかのゾンビはそれほど危険ではありません(実際の場合と同様)。1つの問題は、各ゾンビプロセスが自分のプロセスIDを保持し、Linux / UnixオペレーティングシステムのPIDの数が限られていることです。不適切にプログラムされたソフトウェアが多くのゾンビプロセスを生成する場合、利用可能なプロセスIDがなくなるため、プロセスを開始できなくなる可能性があります。
したがって、彼らが巨大なグループに属している場合、彼らは非常に危険です(多くの映画のように非常によく実証されています)
どうすればゾンビの大群から身を守ることができますか?
頭の中のショットは機能しますが、そのためのコマンドがわかりません(プロセスが既に終了しているため、SIGKILLは機能しません)。
さて、killを介して親プロセスにSIGCHLDを送信できますが、このシグナルを無視した場合はどうなりますか?唯一のオプションは、親プロセスを強制終了し、initプロセスがゾンビを「採用」することです。Initは定期的にwait()
syscallを呼び出して、ゾンビの子をクリーンアップします。
あなたの場合
あなたの場合、SIGCHLDをcrondプロセスに送信する必要があります。
root@host:~# strace -p $(pgrep cron)
Process 1180 attached - interrupt to quit
次に、別の端末から:
root@host:~$ kill -17 $(pgrep cron)
出力は次のとおりです。
restart_syscall(<... resuming interrupted call ...>) = ? ERESTART_RESTARTBLOCK (To be restarted)
--- SIGCHLD (Child exited) @ 0 (0) ---
wait4(-1, 0x7fff51be39dc, WNOHANG, NULL) = -1 ECHILD (No child processes) <-- Here it happens
rt_sigreturn(0xffffffffffffffff) = -1 EINTR (Interrupted system call)
stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=1892, ...}) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {0x403170, [CHLD], SA_RESTORER|SA_RESTART, 0x7fd6a7e9d4a0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({42, 0}, ^C <unfinished ...>
Process 1180 detached
あなたは、参照wait4()
システムコールは-1を返しECHILD、子プロセスが存在しないことを意味します。結論は次のとおりです。cronはSIGCHLDシステムコールに反応し、黙示録を強制するべきではありません。