用SIGHUP重新启动被杀死的进程

我有一个进程,并希望当它被杀害时再次启动它。 为了达到这个目的,我开始使用prctl(PR_SET_PDEATHSIG, SIGHUP); 捕杀其父母并重新开始。

这里是监护人代码(logging省略):

 void restart (int signal) { if (getppid() == 1) { if (fork() == 0) { execl("./process", 0); } exit(1); } } int main() { prctl(PR_SET_PDEATHSIG, SIGHUP, NULL, NULL, NULL); struct sigaction new_action, old_action; new_action.sa_handler = restart; sigemptyset (&new_action.sa_mask); new_action.sa_flags = 0; sigaction (SIGHUP, NULL, &old_action); if (old_action.sa_handler != SIG_IGN) { sigaction (SIGHUP, &new_action, NULL); } while (getppid() != 1) { sleep(86400000); } return 0; } 

和父母:

 int main() { if (fork() == 0) { execl("./guardian", 0); } while (1) { cout << "I am process\n"; sleep(1); } return 0; } 

我遇到的问题是只有一次。 这是第一次启动进程时的ps输出:

 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND 1012 13058 0.0 0.3 20244 1932 pts/1 Ss 08:22 0:00 -sh 1012 22084 0.0 0.1 11484 1004 pts/1 S+ 11:20 0:00 \_ ./process 1012 22085 0.0 0.1 11484 1000 pts/1 S+ 11:20 0:00 \_ [guardian] 1012 12510 0.0 0.3 20784 1712 pts/0 Ss 08:14 0:00 -sh 1012 22088 0.0 0.1 17412 1012 pts/0 R+ 11:20 0:00 \_ ps fu 

这看起来不错。 接下来我用kill -9 22084杀死进程。 再次ps输出:

 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND 1012 13058 0.0 0.3 20244 1932 pts/1 Ss+ 08:22 0:00 -sh 1012 12510 0.0 0.3 20784 1712 pts/0 Ss 08:14 0:00 -sh 1012 22091 0.0 0.1 17412 1012 pts/0 R+ 11:21 0:00 \_ ps fu 1012 22089 0.0 0.1 11484 996 pts/1 S 11:20 0:00 [process] 1012 22090 0.0 0.1 11484 996 pts/1 S 11:20 0:00 \_ [guardian] 

当我杀死进程再次kill -9 22089监护人似乎并没有得到SIGHUPcallback(我从日志中检查,他们在这里省略)。

 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND 1012 13058 0.0 0.3 20244 1932 pts/1 Ss+ 08:22 0:00 -sh 1012 12510 0.0 0.3 20784 1712 pts/0 Rs 08:14 0:00 -sh 1012 22339 0.0 0.1 17412 1008 pts/0 R+ 11:27 0:00 \_ ps fu 1012 22090 0.0 0.1 11484 996 pts/1 S 11:20 0:00 [guardian] 

我的问题是 – 为什么监护人没有得到SIGHUP?

我怀疑它可能有一些与后台进程组的东西 – 当进程重新启动时,它在后台组(比较S +和S在PS统计)。

看起来SIGHUP在处理SIGHUP的信号处理程序中被阻塞。 fork()exec()继承了信号掩码,因此你的第二个守护者永远不会再收到它。

exec() parent之前的fork()之后的信号处理程序中解除SIGHUP