Linux僵尸進程(Zombie Process)是一種特殊的進程狀態,它已經完成了執行,但其父進程尚未調用wait()
或waitpid()
函數來收集其退出狀態。因此,僵尸進程在系統中仍然保留一個進程表項,直到其父進程處理完它的退出狀態或者父進程結束。
僵尸進程的生命周期可以分為以下幾個階段:
SIGCHLD
信號給其父進程。wait()
或waitpid()
),子進程就會變成僵尸進程。ps
命令看到。wait()
或waitpid()
來收集子進程的退出狀態時,僵尸進程會被系統自動回收。為了避免僵尸進程的產生,可以采取以下措施:
SIGCHLD
信號,并在信號處理函數中調用wait()
或waitpid()
來收集子進程的退出狀態。waitpid()
代替wait()
,這樣可以更靈活地控制等待哪個子進程,并且可以避免僵尸進程的產生。以下是一個簡單的示例,展示了如何正確處理子進程的退出狀態以避免僵尸進程:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
void sigchld_handler(int signum) {
int status;
pid_t pid;
// 等待任意一個子進程結束
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
printf("Child process %d exited with status %d\n", pid, WEXITSTATUS(status));
}
}
int main() {
pid_t pid;
// 設置SIGCHLD信號處理函數
signal(SIGCHLD, sigchld_handler);
// 創建子進程
pid = fork();
if (pid == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
if (pid == 0) {
// 子進程
printf("Child process is running\n");
sleep(2); // 模擬子進程工作
printf("Child process is exiting\n");
exit(EXIT_SUCCESS);
} else {
// 父進程
printf("Parent process is waiting for child process to finish\n");
sleep(5); // 父進程等待一段時間
printf("Parent process is exiting\n");
}
return 0;
}
在這個示例中,父進程設置了一個信號處理函數sigchld_handler
來處理SIGCHLD
信號,并在信號處理函數中調用waitpid()
來收集子進程的退出狀態。這樣可以確保即使父進程在子進程之前退出,子進程也不會變成僵尸進程。