573 字
3 分钟
什么是僵尸进程和孤儿进程?如何处理
僵尸进程是已经执行结束、资源大多已释放,但退出状态尚未被父进程 wait 获取的子进程记录。内核暂时保留 PID、退出码和少量统计信息,便于父进程查询。它不再执行用户代码,也不是仍占用完整地址空间的“死进程”;但大量未回收的僵尸会占用 PID 和进程表项。
父进程可通过 wait() 或 waitpid() 回收已退出子进程。服务程序若会创建许多子进程,应在合适位置等待,或处理 SIGCHLD 并循环调用非阻塞 wait,因为一次信号通知可能对应多个已退出子进程。仅设置忽略 SIGCHLD 或特定自动回收选项属于平台相关做法,应理解其语义再采用。
孤儿进程是父进程先于子进程退出的仍在运行的进程。它会被系统中的子收割进程重新收养(Linux 上通常是 init 或配置的 subreaper),之后退出时由新父进程负责回收。孤儿不等于僵尸:孤儿仍可能正常运行;僵尸已经退出,只是等待回收。
排查时可查看进程状态并检查父 PID。僵尸通常表现为已退出等待回收的状态,向它发送普通终止信号无效,因为它已不再运行;应找到并修复未 wait 的父进程。孤儿则需判断服务管理器或容器的 PID 1 是否正确接收并回收子进程。
常见追问
Q:僵尸进程能用 kill 杀掉吗?
A:不能按普通运行进程的方式终止,它已经退出。需要让父进程调用 wait 回收;若父进程失效,父进程退出后由新父进程接管回收。
Q:孤儿进程一定有问题吗?
A:不一定。父进程退出后子进程可继续运行并被系统收养,这是允许的生命周期状态;关键在于其资源和退出状态最终有人管理。
Q:wait 和 waitpid 有什么常见差别?
A:wait 等待任意一个子进程;waitpid 可指定子进程或进程组,并可使用选项实现非阻塞检查等行为。
目录