Bagaimana saya bisa membunuh proses <defunct> yang orang tuanya init?

27

Transmisi sebentar-sebentar tergantung pada NAS saya. Jika saya mengirim SIGTERM, itu tidak hilang dari daftar proses dan <defunct>label muncul di sebelahnya. Jika saya mengirim SIGKILL, itu masih belum hilang dan saya tidak bisa menghentikan orang tua karena orang tuanya init. Satu-satunya cara saya dapat menyingkirkan proses dan me-restart Transmission adalah dengan reboot.

Saya menyadari hal terbaik yang dapat saya lakukan adalah mencoba dan memperbaiki Transmisi (dan saya sudah mencoba), tetapi saya seorang pemula dalam kompilasi dan saya ingin memastikan torrent saya selesai sebelum saya mulai mengacaukannya.

Andy E
sumber
3
Tidak ada yang menyatakan yang jelas ... proses <defunct> yang dimiliki oleh "init" seharusnya tidak mungkin! Ini adalah situasi yang sangat aneh! Apakah kamu yakin
JoelFan
@ JoelFan: Saya hanya mencari itu untuk memastikan bahwa saya tidak melupakan sesuatu yang penting. Zombi yang merupakan anak-anak initharus pergi dengan cukup cepat karena initmenunggu anak-anak secara berkala sebagai salah satu dari banyak tugas umum ... <defunct>sama dengan zombie?
D.Shawley
1
Nevermind ... <defunct>persis sama dengan zombie. initakan menunggu anak-anaknya sehingga ini seharusnya tidak pernah terjadi secara teori. Saya ingin tahu apa yang terjadi jika Anda mengirim SIGCHLDke init?
D.Shawley
@ JoelFan: yeah, saya yakin. Nilai untuk PPID adalah 1 (init), jadi tidak mungkin untuk SIGKILL prosesnya.
Andy E
3
mirip dengan unix.stackexchange.com/a/5648
tshepang

Jawaban:

35

Anda tidak dapat membunuh <defunct>proses (juga dikenal sebagai proses zombie) karena sudah mati. Sistem menjaga proses zombie bagi orang tua untuk mengumpulkan status keluar. Jika orang tua tidak mengumpulkan status keluar maka proses zombie akan tetap ada selamanya. Satu-satunya cara untuk menghilangkan proses-proses zombie adalah dengan membunuh orang tua. Jika orang tua tidak init maka Anda hanya dapat reboot.

Proses zombie hampir tidak membutuhkan sumber daya sehingga tidak ada biaya kinerja untuk membiarkannya bertahan. Meskipun memiliki proses zombie sekitar biasanya berarti ada bug di beberapa program Anda. Init biasanya harus mengumpulkan semua anak. Jika init memiliki anak-anak zombie maka ada bug di init (atau yang lain selain bug itu).

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

lesmana
sumber
9
inittidak pernah dapat memiliki anak zombie. Dari artikel wikipedia: Ketika suatu proses kehilangan induknya, init menjadi induk baru. Init secara berkala mengeksekusi panggilan sistem tunggu untuk menuai zombie apa pun dengan init sebagai induk. Salah satu inittanggung jawab adalah menuai anak yatim dan zombie tanpa orangtua.
D.Shawley
14
@ D.Shawley: initdapat memiliki bug. Penggantian init runitmemiliki bug yang menyebabkan masalah ini.
camh
2
init dapat memiliki anak yang mati, mungkin karena bug, tetapi itu bisa. Karena saya sedang melihatnya sekarang.
studgeek
Ada program ini yang saya jalankan dari terminal dan masuk ke keadaan mati .. Seperti dijelaskan oleh @lesmana, ketika saya menutup terminal (induk) program keluar dengan bersih.
mk ..
6

Siapa pun yang mencoba memperbaiki kode sumber Transmisi C harus membaca tentang trik "garpu ganda" untuk menghindari zombie dan penangan sinyal ... dan bagaimana ia dapat digunakan sebagai bagian dari fungsi spawn pintar variadic (lihat Pemijahan di 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);
nazar
sumber
1
Garpu ganda mencegah proses zombie dengan memaksa kernel untuk mengatur induknya ke PID 1, yang seharusnya membersihkan zombie. Kedengarannya seperti Transmission sudah melakukannya, karena induknya sudah memproses 1.
Jander
1
Ada banyak masalah di sini. # 1: Hanya orang tua yang harus menelepon exit(3); anak-anak harus menelepon _exit(2)sebagai gantinya (jika tidak Anda mendapatkan beberapa stdio flushes, di antara masalah lain). # 2: Itu execvp(3)bisa menggunakan perror(3)jika gagal. # 3: Sebaiknya kamu gunakan signal(SIGCHLD, SIG_IGN)saja semua kekacauan ini
Kevin