原文地址父进程异常退出时,确保子进程退出
前言
父进程异常退出时,如果子进程未退出,或者对于父进程的退出不知情,将会导致子进程变成孤儿进程,更严重的情况是,如果父进程需要使用端口,而父进程异常退出,父进程再次启动时,会发现其子进程占用其端口。原因是,子进程继承了原来父进程的端口。
因此必须保证,父进程异常退出是,子进程也能够退出。
如下面的程序,对系统的system函数进行了改写。
bakRun.sh
#!/bin/bash
declare -i i=1
until ((30<i))
do
let i++
sleep 1
echo "1"
done
exit 0
bakRun.c,编译:gcc -g bakRun.c -o bakRun
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#include<unistd.h>
#include<signal.h>
#include <sys/prctl.h>
#include<sys/wait.h>
int mysystem(const char *cmd)
{
pid_t pid;
int status;
if((pid=fork()) < 0)
{
printf("fork error\n");
}
else if(pid >0)
{
waitpid(pid,&status,0);
printf("parent\n");
}
else
{
printf("receive msg\n");
prctl(PR_SET_PDEATHSIG,SIGHUP);
execl("/bin/sh","sh","-c","./bakRun.sh",(char*)0);
printf("exec cmd\n");
return -1;
}
return 0;
}
int main(int argc ,char* argv[])
{
mysystem("./backRun.sh");
while(1);
return 0;
}
上面的程序中,需要设置选项
prctl(PR_SET_PDEATHSIG,SIGHUP);
设置该选项,在父进程死后,子进程会收到SIGHUP信号,子进程因此也会退出,解决了,父进程异常退出,而子进程来不及回收资源的问题。
如果去掉了上面的设置,在杀死bakRun之后,会发现sh脚本还在运行。