Linux--僵死进程和孤儿进程以及如何杀死僵死进程

    科技2025-02-06  15

    Linux--僵死进程和孤儿进程以及如何杀死僵死进程


    1.僵死进程与孤儿进程的区别?

    父进程和子进程终止关系有两种:父进程先于子进程终止和子进程先于父进程终止。

    孤儿进程:父进程先于子进程终止

    终止进程的父进程更改为init进程,也就是父进程ID更改为1。当一个进程终止时,内核会检查所有的活动进程,找出正要终止进程的子进程,并将其父进程更改为init进程。

    僵死进程:子进程先于父进程终止

    一个进程执行了exit系统调用退出,而其父进程并没有为它收尸(调用wait或waitpid来获得它的结束状态)的进程。

    内核会为每个终止子进程保留一定量的信息,这些信息至少包括进程ID,进程的终止状态,以及该进程使用的CPU时间,所以当终止子进程的父进程调用wait或waitpid时就可以得到这些信息。如果父进程没有调用wait函数的话,则该资源就会一直被占用。

     

    2.如何避免僵死进程?

    1.wait和waitpid函数:父进程调用wait/waitpid等函数等待子进程结束,如果尚无子进程退出wait会导致父进程阻塞。waitpid可以通过传递WNOHANG使父进程不阻塞立即返回。 

    2.sigaction信号处理函数(交给内核处理):如果父进程很忙可以用sigaction注册信号处理函数,在信号处理函数调用wait/waitpid等待子进程退出。(sigaction函数类似于signal函数,而且完全可以代替后者,也更稳定)

    3.signal忽略SIGCHLD信号(交给内核处理) :通过signal(SIGCHLD, SIG_IGN)通知内核对子进程的结束不关心,由内核回收。如果不想让父进程挂起,可以在父进程中加入一条语句:signal(SIGCHLD,SIG_IGN);表示父进程忽略SIGCHLD信号,该信号是子进程退出的时候向父进程发送的。

    4.fork两次:通过两次调用fork。父进程首先调用fork创建一个子进程然后waitpid等待子进程退出,子进程再fork一个孙进程后退出。这样子进程退出后会被父进程等待回收,而对于孙子进程其父进程已经退出所以孙进程成为一个孤儿进程,孤儿进程由init进程接管,孙进程结束后,init会等待回收。

     

    第三种方法忽略SIGCHLD信号,这常用于并发服务器的性能的一个技巧因为并发服务器常常fork很多子进程,子进程终结之后需要服务器进程去wait清理资源。如果将此信号的处理方式设为忽略,可让内核把僵尸子进程转交给init进程去处理,省去了大量僵尸进程占用系统资源

     

    Processed: 0.009, SQL: 8