プロセス/プログラムがゾンビになる理由


13

スクリプトがコマンドラインから正常に実行されている場合、cronを実行した後に同じスクリプトがゾンビ状態になるのはなぜですか?また同じトラブルシューティングの方法は?

以下は実際の例です。

[root@abc ~]# ps ax | grep Z
23880 ?        Zs     0:00 [checkloadadv.sh] <defunct>
23926 pts/0    S+     0:00 grep Z
[root@abc ~]# strace -p 23880
attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted
[root@abc ~]# pstree | grep  checkload
init-+-crond---crond-+-checkloadadv.sh
[root@abc ~]# bash /usr/bin/checkloadadv.sh
System Load is OK : 0.05

トラブルが発生するとトラブルシューティングが行われます。ゾンビは問題ありません。
ジル 'SO-悪であるのをやめる'

@Gilles、あなたは正しいですが、私は気にし、それらを防ぐために見つける必要がありますか?あなたが思うこと ?
ラフルパティル

彼らはトラブルではないので、いや、あなたは気にする必要はありません。
ジル 'SO-悪であるのをやめる'

回答:


21

ここに画像の説明を入力してください

実際のゾンビのように、ゾンビプロセスはすでに死んでいるので、殺すことができません。

どうやって

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システムコールに反応し、黙示録を強制するべきではありません。


1
クリケットのバットやLPはありませんか?
Alexios

-3

親スレッドがその子スレッドの前に強制終了されると、すべての子スレッドがゾンビプロセスになります。


7
真実ではない、彼らはただ親になります。ゾンビプロセスにはwaitpidが呼び出されていません。
クリスダウン

おそらく、彼は親プロセスと子プロセスについて話していたのでしょう。親が「死ぬ」とき、子プロセスは「孤児」になります。
バルン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.