", maka proses Zombie dijana; jika sejumlah besar proses zombie dihasilkan, sistem tidak akan dapat menjana proses baharu kerana tiada nombor proses yang tersedia, jadi proses zombie harus dielakkan."/> ", maka proses Zombie dijana; jika sejumlah besar proses zombie dihasilkan, sistem tidak akan dapat menjana proses baharu kerana tiada nombor proses yang tersedia, jadi proses zombie harus dielakkan.">
Rumah >Operasi dan penyelenggaraan >operasi dan penyelenggaraan linux >Apakah proses zombi linux?
Proses zombie Linux ialah proses yang telah lama mati, tetapi masih menempati kedudukan dalam jadual proses; jika proses induk tidak perlu menunggu() apabila proses anak mati, anda biasanya boleh melihatnya dipaparkan sebagai "
", dengan itu menjana proses zombi; jika sejumlah besar proses zombi dijana, sistem tidak akan dapat menjana proses baharu kerana tiada nombor proses yang tersedia, jadi proses zombi harus dielakkan.
Persekitaran pengendalian tutorial ini: sistem linux5.9.8, komputer Dell G3.
Penjanaan dan pengelakan proses zombi (Proses tidak berfungsi) di bawah Linux
Dalam sistem UNIX, proses tamat, tetapi induknya. Proses tak tunggu (call wait/waitpid) dia, lepas tu dia jadi zombie process. Apabila anda menggunakan arahan ps untuk memerhati status pelaksanaan proses, anda akan melihat bahawa bar status proses ini tidak berfungsi. Proses zombi ialah proses yang telah lama mati, tetapi masih menduduki slot dalam jadual proses.
Tetapi jika proses induk proses itu telah tamat dahulu, maka proses itu tidak akan menjadi proses zombie. Kerana apabila setiap proses tamat, sistem akan mengimbas semua proses yang berjalan dalam sistem semasa untuk melihat sama ada sebarang proses adalah proses anak bagi proses yang baru tamat, proses Init akan mengambil alihnya dan menjadi proses induk. dengan itu memastikan bahawa setiap proses akan mempunyai proses induk. Proses Init secara automatik akan menunggu proses anaknya, jadi semua proses yang diambil alih oleh Init tidak akan menjadi proses zombi.
Setiap proses Unix mempunyai titik masuk (entry) dalam jadual proses, yang digunakan oleh proses teras semasa melaksanakan proses Semua maklumat yang diterima disimpan di pintu masuk. Apabila anda menggunakan arahan ps untuk melihat maklumat proses dalam sistem, apa yang anda lihat ialah data yang berkaitan dalam jadual proses. Apabila proses baharu dibuat dengan panggilan sistem fork(), proses teras akan menetapkan titik masuk kepada proses baharu dalam jadual proses, dan kemudian menyimpan maklumat yang berkaitan dalam jadual proses yang sepadan dengan titik masuk. Salah satu daripada maklumat ini ialah nombor pengenalan proses induknya.
Tamat proses anak dan proses induk adalah proses tak segerak, iaitu proses ibu bapa tidak boleh meramalkan bila proses anak akan tamat. Jadi adakah maklumat status apabila proses anak tamat akan hilang kerana proses ibu bapa terlalu sibuk untuk menunggu proses anak, atau kerana tidak tahu bila proses anak akan tamat?
Tidak. Kerana UNIX menyediakan mekanisme untuk memastikan bahawa selagi proses induk ingin mengetahui maklumat status apabila proses anak tamat, ia boleh mendapatkannya. Mekanisme ini ialah: apabila proses kanak-kanak melengkapkan kitaran hayatnya, ia akan melaksanakan panggilan sistem exit(), dan kernel mengeluarkan semua sumber proses, termasuk fail terbuka, memori yang diduduki, dsb. Walau bagaimanapun, maklumat tertentu masih dikekalkan untuknya (termasuk ID proses, kod keluar, status penamatan proses, jumlah masa CPU yang diambil oleh proses, dll.), dan data ini akan disimpan sehingga sistem Lulus kepada proses induknya dan tidak melepaskannya sehingga proses induk mengambilnya melalui tunggu/waitpid.
Dengan kata lain, apabila sesuatu proses itu mati, ia tidak hilang sepenuhnya. Proses ini ditamatkan, ia tidak lagi berjalan, tetapi masih terdapat beberapa baki data menunggu proses induk untuk menuntutnya semula. Apabila proses induk forks() proses anak, ia mesti menggunakan wait() (atau waitpid()) untuk menunggu proses anak keluar. Tindakan tunggu() inilah yang menjadikan data sisa proses anak hilang.
Jika proses induk tidak memanggil tunggu/tunggu, maklumat yang disimpan tidak akan dikeluarkan, dan nombor prosesnya akan sentiasa diduduki, tetapi sistem Kapasiti jadual proses adalah terhad, dan nombor proses yang boleh digunakan juga terhad Jika sejumlah besar proses zombi dijana, sistem tidak akan dapat menjana proses baharu kerana tiada nombor proses yang tersedia.
Oleh itu, proses yang tidak berfungsi bukan sahaja menduduki sumber ingatan sistem dan menjejaskan prestasi sistem, tetapi juga menyebabkan kelumpuhan sistem jika jumlahnya terlalu banyak. Selain itu, oleh kerana penjadual tidak boleh memilih proses Defunct, arahan bunuh tidak boleh digunakan untuk memadam proses Defunct Satu-satunya cara adalah dengan memulakan semula sistem.
Jika proses induk tidak perlu menunggu() apabila proses anak mati, anda biasanya boleh menggunakan ps untuk melihat bahawa ia dipaparkan sebagai "81cdbe72de39df0f5a796b0d32341a52 #includeda996ff59ef1c1fa2f19eea6833e0f6c main() { if(!fork()) { printf(“child pid=%d\n”, getpid()); exit(0); } sleep(20); printf(“parent pid=%d \n”, getpid()); exit(0); }
当上述程序以后台的方式执行时,第17行强迫程序睡眠20秒,让用户有时间输入ps -e指令,观察进程的状态,我们看到进程表中出现了defunct进程。当父进程执行终止后,再用ps -e命令观察时,我们会发现defunct进程也随之消失。这是因为父进程终止后,init 进程会接管父进程留下的这些“孤儿进程”(orphan process),而这些“孤儿进程”执行完后,它在进程表中的进入点将被删除。如果一个程序设计上有缺陷,就可能导致某个进程的父进程一直处于睡眠状态或是陷入死循环,父进程没有wait子进程,也没有终止以使Init接管,该子进程执行结束后就变成了defunct进程,这个defunct 进程可能会一直留在系统中直到系统重新启动。
在看一个产生僵尸进程的例子。
子进程要执行的程序test_prog
//test.c
#include ade979de5fc0e1ca0540f360a64c230b int main() {
int i = 0;
for (i = 0 ; i 71daab767444cb0914b6ac4e5d2a5306
总结:子进程成为 defunct 直到父进程 wait(),除非父进程忽略了 SIGCLD 。更进一步,父进程没有 wait() 就消亡(仍假设父进程没有忽略 SIGCLD )的子进程(活动的或者 defunct)成为 init 的子进程,init 着手处理它们。
1、父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起。
在上个例子中,如果我们略作修改,在第8行sleep()系统调用前执行wait()或waitpid()系统调用,则子进程在终止后会立即把它在进程表中的数据返回给父进程,此时系统会立即删除该进入点。在这种情形下就不会产生defunct进程。
2. 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler。在子进程结束后,父进程会收到该信号,可以在handler中调用wait回收。
3. 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCLD, SIG_IGN)或signal(SIGCHLD, SIG_IGN)通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收,并不再给父进程发送信号
4. fork两次,父进程fork一个子进程,然后继续工作,子进程fork一个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收还要自己做。 下面就是Stevens给的采用两次folk避免僵尸进程的示例:
#include "apue.h" #include 069d3d88bce9f46cf91e8b21a3bb1b3f int main(void) ...{
pid_t pid;
if ((pid = fork()) 7556d38bf89e4c298ea18b0165fac49b 0)
exit(0); /**//* parent from second fork == first child */
/**//*
* We're the second child; our parent becomes init as soon
* as our real parent calls exit() in the statement above.
* Here's where we'd continue executing, knowing that when
* we're done, init will reap our status.
*/
sleep(2);
printf("second child, parent pid = %d ", getppid());
exit(0);
}
if (waitpid(pid, NULL, 0) != pid) /**//* wait for first child */
err_sys("waitpid error");
/**//*
* We're the parent (the original process); we continue executing,
* knowing that we're not the parent of the second child.
*/
exit(0); }
相关推荐:《Linux视频教程》
Atas ialah kandungan terperinci Apakah proses zombi linux?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!