今天登陆到服务器上时,系统打印有6 zombie processes存在,因而用kill -9去清理掉这些僵尸进程,命令执行完后没有错误,但是再次查找时,发现僵尸进程仍然存在,不知道怎么清理了,上网找了一下,学习一下。 linux
在UNIX 系统中,一个进程结束了,可是他的父进程没有等待(调用wait / waitpid)他, 那么他将变成一个僵尸进程. 在fork()/execve()过程当中,假设子进程结束时父进程仍存在,而父进程fork()以前既没安装SIGCHLD信号处理函数调用 waitpid()等待子进程结束,又没有显式忽略该信号,则子进程成为僵尸进程。
如何查看linux系统上的僵尸进程,如何统计有多少僵尸进程?
shell
#ps -ef | grep defunct或者
#ps aux | grep defunct
或者查找状态为Z的进程,Z就是表明zombie process,僵尸进程的意思。
另外使用top命令查看时有一栏为S,若是状态为Z说明它就是僵尸进程。top命令中也统计了僵尸进程。
Tasks: 95 total, 1 running, 94 sleeping, 0 stopped, 0 zombie
服务器
top - 10:05:03 up 11 days, 1:17, 7 users, load average: 0.00, 0.01, 0.05 Tasks: 178 total, 1 running, 174 sleeping, 3 stopped, 0 zombie
通常僵尸进程很难直接kill掉,不过您能够kill僵尸爸爸。父进程死后,僵尸进程成为”孤儿进程”,过继给1号进程init,init始终会负责清理僵尸进程.它产生的全部僵尸进程也跟着消失。
并发
# ps -e -o ppid,stat | grep Z | cut -d‘ ’ -f1 | xargs kill -9另外子进程死后,会发送SIGCHLD信号给父进程,父进程收到此信号后,执行waitpid()函数为子进程收尸。就是基于这样的原理:就算父进程没有调用wait,内核也会向它发送SIGCHLD消息,而此时,尽管对它的默认处理是忽略,若是想响应这个消息,能够设置一个处理函数。
处理SIGCHLD信号并非必须的。但对于某些进程,特别是服务器进程每每在请求到来时生成子进程处理请求。若是父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源。若是父进程等待子进程结束,将增长父进程的负担,影响服务器进程的并发性能。在Linux下 能够简单地将 SIGCHLD信号的操做设为SIG_IGN。
函数
signal(SIGCHLD,SIG_IGN);这样,内核在子进程结束时不会产生僵尸进程。这一点与BSD4不一样,BSD4下必须显式等待子进程结束才能释放僵尸进程。