父进程异常退出时,确保子进程退出

前言

父进程异常退出时,如果子进程未退出,或者对于父进程的退出不知情,将会导致子进程变成孤儿进程,更严重的情况是,如果父进程需要使用端口,而父进程异常退出,父进程再次启动时,会发现其子进程占用其端口。原因是,子进程继承了原来父进程的端口。

因此必须保证,父进程异常退出是,子进程也能够退出。

如下面的程序,对系统的system函数进行了改写。
bakRun.sh

1
2
3
4
5
6
7
8
9
#!/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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

#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脚本还在运行。

守望 wechat
关注公众号[编程珠玑]获取更多原创技术文章
出入相友,守望相助!