Seperti zombie yang sebenarnya, proses zombie tidak bisa dibunuh, karena sudah mati.
Bagaimana itu terjadi?
Ketika di Linux / Unix suatu proses mati / berakhir semua informasi dari proses akan dihapus dari memori sistem, hanya deskriptor proses tetap. Prosesnya dalam keadaan Z (zombie). Proses induknya mendapat sinyal dari kernel:, SIGCHLD
itu berarti bahwa salah satu proses anaknya keluar, terganggu atau dilanjutkan setelah terganggu (dalam kasus kami hanya keluar).
Proses induk sekarang perlu menjalankan wait()
syscall untuk membaca status keluar dan informasi lain dari proses anaknya. Kemudian deskriptor dihapus dari memori dan prosesnya bukan lagi zombie.
Jika proses induk tidak pernah memanggil wait()
syscall, deskriptor proses zombie tetap ada dalam memori dan makan otak. Biasanya Anda tidak melihat proses zombie, karena prosedur di atas memakan waktu lebih sedikit.
Fajar orang mati
Setiap deskriptor proses membutuhkan jumlah memori yang sangat kecil, sehingga beberapa zombie tidak terlalu berbahaya (seperti dalam kehidupan nyata). Satu masalah adalah bahwa setiap proses zombie menyimpan id prosesnya, dan sistem operasi Linux / Unix memiliki jumlah pid yang terbatas. Jika perangkat lunak yang tidak terprogram menghasilkan banyak proses zombie, dapat terjadi bahwa proses tidak dapat dimulai lagi karena tidak ada lagi id proses yang tersedia.
Jadi, jika mereka berada dalam kelompok besar mereka sangat berbahaya (seperti di banyak film dipertunjukkan dengan sangat baik)
Bagaimana kita bisa mempertahankan diri melawan gerombolan zombie?
Tembakan di kepala akan berhasil, tetapi saya tidak tahu perintah untuk itu (SIGKILL tidak akan bekerja karena prosesnya sudah mati).
Nah, Anda dapat mengirim SIGCHLD via kill ke proses induk, tetapi ketika mengabaikan sinyal ini, lalu bagaimana? Satu-satunya pilihan Anda adalah untuk membunuh proses induk dan bahwa proses init "mengadopsi" zombie. Init secara berkala memanggil wait()
syscall untuk membersihkan anak-anak zombie-nya.
Dalam kasus Anda
Dalam kasus Anda, Anda harus mengirim SIGCHLD ke proses crond:
root@host:~# strace -p $(pgrep cron)
Process 1180 attached - interrupt to quit
Kemudian dari terminal lain:
root@host:~$ kill -17 $(pgrep cron)
Outputnya adalah:
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
Anda melihat wait4()
syscall mengembalikan -1 ECHILD, yang berarti bahwa tidak ada proses anak di sana. Jadi kesimpulannya adalah: cron bereaksi terhadap panggilan SIGCHLD dan tidak boleh memaksakan kiamat.