为什么SIGHUP信号在成为孤立进程组时没有收到

在关于孤立进程组的 GNU libc手册中,提到:

“process groups that continue running even after the session leader has terminated are marked as orphaned process groups. When a process group becomes an orphan, its processes are sent a SIGHUP signal. Ordinarily, this causes the processes to terminate. However, if a program ignores this signal or establishes a handler for it (see Signal Handling), it can continue running as in the orphan process group even after its controlling process terminates; but it still cannot access the terminal any more. ” 

我写了一个testing程序,但是当进程组成为一个孤儿时,它的进程没有收到SIGHUP信号。 我想知道为什么?

 #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> static void sig_hup(int signo) //**never get called ???** { printf("SIGHUP received, pid = %ld\n", (long)getpid()); } static void pr_ids(char *name) { printf("%s: pid = %ld, ppid = %ld, pgrp = %ld, tpgrp = %ld\n", name, (long)getpid(), (long)getppid(), (long)getpgrp(), (long)tcgetpgrp(STDIN_FILENO)); fflush(stdout); } int main(void) { char c; pid_t pid; pr_ids("parent"); pid = fork(); if (pid > 0) { // parent sleep(5); exit(0); // parent exit; } else { pr_ids("child"); setsid(); //create new session, and "child" becomes the session leader pid = fork(); if(pid>0) { sleep(20); exit(0); // "child" exit // so the process group become an orphan process group } else{ pr_ids("grandson"); signal(SIGHUP, sig_hup); // establish signal handler sleep(60); // now becoming orphan process group printf("end\n"); } } exit(0); } 

该文件部分正在谈论一个进程的控制终端丢失,通常是由一个调制解调器挂断,或虚拟等效(结束一个ssh会话等)。 (我认为文件中的措辞可以在这里改进)。 当你在这里使用setsid() ,你放弃了由setsid()返回的时间访问控制终端,所以没有控制终端从那里丢失。

你可以open()一个tty设备(例如一个pty slave)来获得一个控制终端(注意你可能还需要做一些额外的操作 – FreeBSD需要一个TIOCSCTTY ioctl),然后再丢失它, 然后你应该得到SIGHUP信号。

孤立的进程组获得SIGHUP,紧随其后的是SIGCONT,如果它们在成为孤儿时停止。

睡眠不够,你需要:

 kill(getpid(), SIGSTOP); 

除此之外,如果setprgrp()是由setsid()setprgrp()引起的,那么POSIX并不要求发送SIGHUP和SIGCONT,因为那么这不是由于一个退出的进程不知道作业控制(见http:/ / /pubs.opengroup.org/onlinepubs/9699919799/functions/_exit.html )。

但是,如果使用kill(getpid(), SIGSTOP)而不是该子kill(getpid(), SIGSTOP)中的sleep(60) ,则即使不调用setsid()程序也会得到一个停止的孤行。

 #define _GNU_SOURCE #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/types.h> #include <sys/wait.h> #include <unistd.h> #include <signal.h> static void sig_hup(int signo) //**never get called ???** { printf("SIGHUP received, pid = %ld\n", (long)getpid()); } static void pr_ids(char *name) { printf("%s: pid = %ld, ppid = %ld, pgrp = %ld, tpgrp = %ld\n", name, (long)getpid(), (long)getppid(), (long)getpgrp(), (long)tcgetpgrp(STDIN_FILENO)); fflush(stdout); } int main(void) { pid_t pid; pr_ids("parent"); pid = fork(); if (pid > 0) { // parent sleep(5); _exit(0); // parent exit; } else { pr_ids("child"); /*setsid(); //create new session, and "child" becomes the session leader*/ pid = fork(); if(pid>0) { sleep(2); exit(0); // "child" exit // so the process group become an orphan process group } else{ pr_ids("grandson"); signal(SIGHUP, sig_hup); // establish signal handler kill(getpid(), SIGSTOP); printf("end\n"); } } exit(0); } 

在父母死后(5s),应该给你一个SIGHUP。