什么是僵尸进程
僵尸进程(Zombie Process)是指已完成执行但仍在进程表中保留条目的子进程。这类进程已经释放了大部分资源,但仍在内核中保留少量信息(如进程ID、退出状态等),等待父进程读取其退出状态。若父进程未正确处理,僵尸进程会持续占用系统资源。
查找僵尸进程的方法
使用ps命令
通过ps命令结合STAT列筛选僵尸进程。僵尸进程的状态通常显示为Z或Z+。执行以下命令:
ps aux | grep 'Z'
或更精确地筛选:
ps -eo pid,ppid,stat,cmd | grep '^[ Z]'
结合top命令
在top命令界面中,观察进程列表的S列(状态列)。僵尸进程会标记为Z。启动top后按Shift + M可按内存排序,便于发现异常进程。
使用pstree工具
通过树状结构查看父子进程关系,僵尸进程通常会显示为<defunct>:
pstree -p | grep -A 10 '<defunct>'
处理僵尸进程的步骤
终止父进程
找到僵尸进程的父进程ID(PPID),通过kill命令终止父进程以释放资源:
kill -9 <PPID>
系统会自动回收僵尸进程。
手动清除
若父进程为init(PID=1),需重启系统才能彻底清除。临时解决方案是通过proc文件系统强制移除:
echo <PID> > /proc/sys/kernel/ns_last_pid
预防僵尸进程的建议
| 方法 | 说明 |
|---|---|
父进程正确处理SIGCHLD |
在父进程代码中捕获SIGCHLD信号,调用waitpid()回收子进程资源。 |
| 避免频繁创建短期进程 | 减少进程创建频率,改用线程或进程池管理。 |
| 监控工具定期检查 | 使用cron任务定时运行ps或专用监控工具(如monit)检测僵尸进程。 |
示例代码:捕获SIGCHLD信号
以下C代码片段演示如何避免僵尸进程:
#include <signal.h>
#include <sys/wait.h>
void sigchld_handler(int sig) {
while (waitpid(-1, NULL, WNOHANG) > 0);
}
int main() {
signal(SIGCHLD, sigchld_handler);
// 主程序逻辑
return 0;
}