承接上篇孤兒進程概念,本文聚焦殭屍進程:子進程結束而父進程未 wait/waitpid 回收,導致進程描述符滯留於系統進程表中,狀態顯示為 <defunct>。
exit() 終止。wait() 或 waitpid() 讀取退出狀態。#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
pid_t pid = fork();
if (pid == -1) {
perror("fork");
exit(1);
} else if (pid == 0) { // 子進程
printf("child_pid pid=%d, ppid=%d\n", getpid(), getppid());
exit(0); // 立即結束
}
// 父進程:不呼叫 wait,直接睡眠並查看進程狀態
sleep(3);
system("ps"); // 列出當前進程
exit(0);
}
$ ./a.out
child_pid pid=1108, ppid=1107
PID TTY TIME CMD
847 pts/1 00:00:00 bash
1107 pts/1 00:00:00 a.out
1108 pts/1 00:00:00 a.out <defunct> <-- 殭屍進程
1109 pts/1 00:00:00 ps
wait()/waitpid() 回收。SIGCHLD 信號處理函數,在 handler 中 waitpid(-1, NULL, WNOHANG) 非阻塞回收。| 特性 | 孤兒進程 | 殭屍進程 |
|---|---|---|
| 父進程狀態 | 已終止 | 仍在運行 |
| 收養者 | init (PID 1) | 無(等待父進程回收) |
| 資源洩漏 | 無(init 會回收) | 是(佔用 PID、進程表項) |
| ps 狀態 | 正常 | <defunct> |
理解兩者區別,是編寫健壯多進程 Linux 程式的基礎功課。