避免僵屍進程的三種方法
在unix係統中,如果一個子進程終止了,而父進程又沒有對子進程進行wait/waitpid,那麼子進程就會成為一個僵屍進程。
用命令ps -ef | grep zombie可以查看係統中是否出現僵屍進程。
僵屍進程是無法用kill 殺死,因為進程已經不存在了,但卻在進程表裏麵占據一個項。如果當係統中出現過多的僵屍進程,
那麼係統將無法再開啟另外的進程,因為進程表已經滿了。這個時候就隻有重新啟動,但reboot是沒有用的,因為係統要執行reboot必須要創建進程。這是讓人非常惱火的事情。
避免僵屍進程
1.wait/waitpid
程序通過wait/waitpid等待子進程結束,並清理進程表.
2.兩次fork
對於一些父進程不希望等待子進程結束的程序,可以通過兩次fork來避免僵屍進程
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid;
pid = fork();
if (pid < 0)
{
perror(”fork”);
}
else if (pid == 0)
{ // 第一個子進程
pid = fork();
if (pid < 0)
{
perror(”fork”);
}
else if (pid > 0)
{
exit(0); //第二個子進程的父進程終止(第一個子進程)
}
sleep(2); //保證父進程優先運行(第一個子進程)
exit(0); //第二個子進程終止
}
if (waitpid(pid, NULL, 0) != pid) //等待第一個子進程
perror(”fork”);
exit(0); //第一個父進程終止
}
當父進程比子進程先終止時,子進程會被init進程接管,當子進程終止後會被init清理。
3.通過對SIGCHLD信號處理
void sig_chld(int signo)
{
pid_t pid;
int stat;
while((pid = waitpid(-1, &stat, WNOHANG)) > 0) {
printf(”child %d terminated\n”, pid);
}
return;
}
int main(void)
{
int rc;
rc = 0;
signal(SIGCHLD, &sig_chld);
return (rc);
}
在子進程終止時,父進程會收到SIGCHLD信號,可以在這個時候進行處理。也可以忽略此信號。但是忽略SIGCHLD信號並不是對所有的係統都有用
最後更新:2017-01-04 22:34:34