#include "myapue.h" #include <errno.h> static void sig_hup(int signo) { 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"); if((pid = fork()) < 0) err_sys("fork error"); else if(pid > 0){ sleep(5); } else{ pr_ids("child"); signal(SIGHUP, sig_hup); kill(getpid(), SIGTSTP);//向子进程自己发出挂起信号,stop ourself pr_ids("child"); if(read(STDIN_FILENO, &c, 1) != 1) printf("read error %d on controlling TTY\n", errno); } exit(0); }
<245>9.10孤儿进程组
(1)
getpid():返回调用进程的进程ID。
getppid():返回调用进程的父进程ID。
getpgrp():返回调用进程的进程组ID。(同一进程组中的各个进程接收来自同一终端的各种信号)
tcgetpgrp(int fd):若成功,返回前台进程组ID。它与在fd上打开的终端相关联。
前台进程组:终端设备驱动程序将终端输入和终端产生的信号发送到此处。
fflush(FILE *fp):强制冲洗一个流,使该流所有未写的数据都被传送至内核。
<118>若fp为NULL,则所有输出流被冲洗。
stdout:标准I/O常量,定义在头文件<stdio.h>中。
STDIN_FILENO:标准输入的文件描述符。
(2)
signal函数<256>:此函数是UNIX信号机制最简单的接口。用于建立信号处理程序。
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
signum参数是信号名
SIGHUP:(挂断信号)终端接口检测到一个连接断开,则将此信号送给与该终端相关的控制进程(会话首进程)。
(此处,在父进程终止后,进程组包含一个停止的进程,进程组成为孤儿进程组,POSIX.1要求向新孤儿进程组中处于停止状态的每一个进程发送挂断信号)
handler:当接到此信号后要调用的函数的地址。或为常量SIG_IGN,SIG_DFL。
(3)<267>
kill函数:将信号发送给进程或进程组。
SIGTSTP:(此处将停止子进程)交互停止信号,当用户在终端上按挂起键时,终端驱动程序产生此信号。该信号发送至前台进程组中的所有进程。
(4)
孤儿进程:父进程已终止的进程,由init进程(进程ID为1)“收养”。
孤儿进程组:<245>
(5)
父进程终止时,子进程变成后台进程组,因为父进程由shell作为前台作业执行。当后台进程组试图读控制终端时,对该后台进程组产生SIGTTIN。