什么是僵尸进程?
僵尸进程(zombie process)是已经终止但其父进程尚未释放其进程描述符的进程。它仅占用一个进程号,不占用任何系统资源。
简单来说就是:僵尸进程就是没死透的进程
创建一个僵尸进程
我们先创建一个僵尸进程
用C语言写一个僵尸进程
cat > zombie.c << EOF
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h> // 添加stdlib.h头文件
int main() {
pid_t pid;
/* 创建子进程 */
pid = fork();
if (pid < 0) {
fprintf(stderr, "Fork Failed\n");
return 1;
} else if (pid == 0) {
printf("Child process\n");
exit(1); // 使用exit系统调用
} else {
printf("Parent process\n");
while (1) {
sleep(1);
}
}
return 0;
}
EOF
gcc -o zombie zombie.c
#编译
./zombie &
#让它后台执行
##怎么查看僵尸进程
ps ax -o stat,ppid,pid,cmd | egrep ^[Zz]
ax #查看所有进程
-o #自定义输出项
stat #是类型 ppid 是进程的父进程号 pid 进程号 cmd 进程名
查看一下
[root@harbor c]# ps ax -o stat,ppid,pid,cmd | egrep ^[Zz]
Z 39026 39027 [zombieproc] <defunct>
#上面找个就是僵尸进程
#其实过滤出Z就可以之间看到僵尸进程
[root@harbor c]# ps ax | grep Z
39027 pts/0 Z 0:00 [zombieproc] <defunct>
40397 pts/0 S+ 0:00 grep --color=auto Z #这个是grep的进程
ps aux | grep Z | grep -v grep
#用-v 过滤掉grep的进程
如何杀死僵尸进程
有几种方法可以终止或清理僵尸进程:
发送SIGCHLD信号给父进程
这个信号将通知父进程回收子进程资源,清理僵尸进程。可以使用kill命令:
kill -SIGCHLD 父进程PID
结束父进程
若结束父进程,则僵尸进程会被init进程收养,从而释放资源。
kill 父进程PID
使用wait或waitpid函数
在父进程中调用wait或waitpid函数,可直接清理僵尸进程。
直接kill僵尸进程
强制结束僵尸进程,但是这种方法不推荐,因为资源可能无法完全释放。
kill -9 僵尸进程PID
重启系统
重新启动后僵尸进程将自动被清除。
使用ps -ef命令找出父进程
之后再根据父进程情况针对性地结束父进程或发送信号。
实例
[root@harbor c]# ps aux | grep Z | grep -v grep
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 39027 0.0 0.0 0 0 pts/0 Z 22:45 0:00 [zombieproc] <defunct>
#得到僵尸进程进程号
pstree -p -s sh
#用僵尸进程进程号查到父进程
[root@harbor c]# pstree -p -s 39027
systemd(1)───sshd(1269)───sshd(2074)───bash(2078)───zombieproc(39026)───zombieproc(39027)
[root@harbor c]# kill -9 39026
#kill掉父进程,就ok了
如果觉得一个不够看用for循环来一百个
cat > zombie100.c << EOF
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h> //添加头文件
int main() {
pid_t pid;
int i;
for (i = 0; i < 100; i++) {
pid = fork();
if (pid < 0) {
fprintf(stderr, "Fork Failed\n");
return 1;
} else if (pid == 0) {
printf("Child %d created\n", i);
exit(1); //使用exit调用
} else {
// Parent process
printf("Parent: Created child %d\n", i);
}
}
while (1) {
sleep(1);
}
return 0;
}
EOF