一、孤儿进程组
1. 孤儿进程的定义:
定义1:该进程组的每个成员的父进程要么是该组的成员,要么在其它会话中。
定义2:一个进程不是孤儿进程组的条件是——该组有一个进程,其父进程在属于同一会话的另一个组中。
只要能够满足上面其中的任一个定义,则此进程组就是孤儿进程组。可能读起来比较拗口,看图 1 中的例子可能会清楚点。
图 1 中,按照孤儿进程组的定义:
- 进程组 1 不是孤儿进程组,因为进程组 1 中有一个进程的父进程不属于进程组 1,也不在另一个会话中。
- 进程组 2 是孤儿进程组,因为该组中的每个成员满足定义:每个成员的父进程要么在本组中,要么在其它会话中。
2. 孤儿进程组的特性:
如果进程组存在停止状态的进程,当该进程组变成孤儿进程组时,POSIIX.1要求向新孤儿进程组中的每一个进程发送挂断(SIGHUP),接着又向其发送继续信号(SIGCONT)。
3. 测试代码:
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <errno.h>void handler(int signo)
{printf("SIGHUP receive, pid = %d\n", getpid());
}void pr_ids(char* name)
{printf("%s: pid = %d, ppid = %d, pgrp = %d, tpgrp = %d\n", name,getpid(), getppid(), getpgid(getpid()), tcgetpgrp(0));fflush(stdout);
}int main()
{char c;pid_t pid;pr_ids("parent");pid = fork();if (pid < 0){perror("fork");}else if (pid > 0){sleep(5);}else{pr_ids("child");signal(SIGHUP, handler);kill(getpid(), SIGTSTP); // 让子进程暂停pr_ids("child"); // 如果执行了此行,说明已经收到了 SIGHUP 信号if (read(STDIN_FILENO, &c, 1) != 1)printf("read error, error number: %d\n", errno);}exit(0);
}
输出结果:
参考资料
1. 孤儿进程与孤儿进程组