分类:
2008-11-28 13:58:15
9.10 orphaned process group
一个process group里的所有的process,要么他们的父亲都是本process group里的进程(很少见),要么他们的父亲都是别的session力的进程(比如init就是在一个与我们启动的程序不同的sessionl里),此时我们说这个process group是一个orphaned process group.
反之,如果说一个process group不是orphaned process group的话,就的要求该process group里至少有一个进程的父亲是本seesion里另外的process group的成员。
Orphaned process group的概念有什么意义:
1.一旦一个process group成为了orphaned process group,那么就意味着没有别的进程可以通过方便的唤醒该process group内可能被stopped的进程了,所以系统应该向该process group内已经被stopped的进程发送hang-up signal (SIGHUP) followed by the continue signal (SIGCONT).
2.如何产生一个orphaned process呢?
在我们的login shell里(bash),fork一个进程A,此时,这个进程和我们的login shell属于同一session内不同的process group(这是bash的特性),并且A的parent为login shell。然后A再fork一个进程B,这个process group里的进程A的父亲是login shell,且不在同一个process group里,所以这个process group不是orphaned process group。此时,如果A退出,那么,B的父亲就成了init进程的孩子,而init进程属于另外的session。所以这个process group成了orphaned process group了。
3.一个成了orphaned process group的进程应该是肯定就成了background process group。即丢掉了对其controlling terminal的控制的。如果其中的process 再次访问controlling terminal,比如read(STDIN_FILENO),按理说就应该收到SIGTTIN信号(因为你是background process)。但是如果系统让他因此而被stopped的话就没有人再去唤醒他了,所以系统发送SIGTTIN信号,而仅仅让他的read返回错误,并将errno置为EIO。
如下就是建立一个orphaned process group的例子:
#include "apue.h"
#include
static void
sig_hup(int signo)
{
printf("SIGHUP received, pid = %d\n", getpid());
}
static void
pr_ids(char *name)
{
printf("%s: pid = %d, ppid = %d, pgrp = %d, tpgrp = %d\n",
name, getpid(), getppid(), getpgrp(), 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) { /* parent */
sleep(5); /*sleep to let child stop itself */
exit(0); /* then parent exits */
} else { /* child */
pr_ids("child");
signal(SIGHUP, sig_hup); /* establish signal handler */
kill(getpid(), SIGTSTP); /* stop ourself */
pr_ids("child"); /* prints only if we're continued */
if (read(STDIN_FILENO, &c, 1) != 1)
printf("read error from controlling TTY, errno = %d\n",
errno);
exit(0);
}
}
结果:
$ ./a.out
parent: pid = 6099, ppid = 2837, pgrp = 6099, tpgrp = 6099
child: pid = 6100, ppid = 6099, pgrp = 6099, tpgrp = 6099
$ SIGHUP received, pid = 6100
child: pid = 6100, ppid = 1, pgrp = 6099, tpgrp = 2837
read error from controlling TTY, errno = 5