首先需要说明的是,exec后,子进程和父进程属于不同的代码段。信号处理函数不会被继承,但是某些针对信号的设置,还是可以传递的,比如exec前,设置信号处理为SIG_IGN,则exec后,该信号依然保持SIG_IGN属性。
下面举例说明,查看如下代码:
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <stdlib.h>
#include <errno.h>
typedef void (*SIGFUNCTYPE)(int);
SIGFUNCTYPE Signal_(int sig, void (*handler)(int))
{
struct sigaction act, oact;
act.sa_handler = handler;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaddset(&act.sa_mask, sig);
if(sigaction(sig, &act, &oact) == -1){
oact.sa_handler = (void (*)())SIG_ERR;
}
return(oact.sa_handler);
}
int main()
{
int pid = fork();
if(pid == 0)
{
//Signal_(SIGHUP, SIG_IGN);
execl("/usr/bin/sleep", "sleep", "1000", NULL);
exit(0);
}
int sid1 = getsid(getpid());
printf("in parent process, session id is %d\n", sid1);
sleep(600);
//while(1);
return 0;
}
该程序名叫做forktest3,终端上运行./forktest3 &;放入后台运行,可以看到后台有两个进程:forktest3和sleep 1000。
然后关闭掉终端,可以发现这两个进程都消失了。
然后放开上面被屏蔽的代码Signal_(SIGHUP, SIG_IGN);终端上运行./forktest3 &;放入后台运行。
然后关闭掉终端,可以发现forktest3消失了,但是sleep 1000还在。
说明Signal_(SIGHUP, SIG_IGN);设置后,尽管后面调用了exec,但是该信号设置依然有效。
而实际上,nohup命令启动进程时,就是这样实现的。