web-dev-qa-db-ja.com

親がinitである<defunct>プロセスを強制終了するにはどうすればよいですか?

NASで送信が断続的に停止しています。 SIGTERMを送信しても、プロセスリストから消えず、その横に<defunct>ラベルが表示されます。 SIGKILLを送信しても、SIGKILLは消えず、親がinitであるため、親を終了できません。プロセスを削除してTransmissionを再起動する唯一の方法は、再起動することです。

私ができる最善のことは、Transmissionを試して修正することです(そして私は試しました)が、私はコンパイルの初心者であり、それをいじり始める前に急流が終了したことを確認したかったのです。

27
Andy E

<defunct>プロセス(ゾンビプロセスとも呼ばれます)は既に終了しているため、強制終了できません。システムは、親が終了ステータスを収集できるようにゾンビプロセスを保持します。親が終了ステータスを収集しない場合、ゾンビプロセスは永久に残ります。これらのゾンビプロセスを取り除く唯一の方法は、親を殺すことです。親がinitの場合、再起動のみできます。

ゾンビプロセスはリソースをほとんど消費しないので、ゾンビプロセスを長引かせることによるパフォーマンスコストはありません。ゾンビプロセスが存在することは、通常、一部のプログラムにバグがあることを意味します。 Initは通常、すべての子を収集する必要があります。 initにゾンビの子がいる場合は、initにバグがあります(または他のバグがあります)。

http://en.wikipedia.org/wiki/Zombie_process

35
lesmana

Transmission Cのソースコードを修正しようとする人は、ゾンビとシグナルハンドラーを回避するための「ダブルフォーク」のトリックと、それをスマート可変スポーン関数の一部として使用する方法( Unixでの起動 )。

excerpt from: 
   "Spawning in Unix", http://lubutu.com/code/spawning-in-unix

Double fork
This trick lets you spawn processes whilst avoiding zombies, without 
installing any signal handler. The first process forks and waits for its 
child; the second process forks and immediately exits and is reaped;
the third process is adopted by init, and executes the desired program. 
All zombies accounted for, since init is always waiting.

if(fork() == 0) {
   if(fork() == 0) {
       execvp(file, argv);
       exit(EXIT_FAILURE);
   }
   exit(EXIT_SUCCESS);
}
wait(NULL);
6
nazar