《UNIX环境高级编程》笔记--孤儿进程组

POSIX.1将孤儿进程组定义为:该组中每个成员的父进程要么是该组的一个成员,要么不是该组所属会话的成员。一个进程组

不是孤儿进程组的条件是:该组中有一个进程,其父进程在属于同一会话中的另一个组中。

下面对孤儿进程组的产生进行检验:

1.在一个具有作业控制的shell中,执行一个程序,该程序fork了一个子进程,其进程结构如下:


2.父进程休眠5秒钟,这是一种让子进程在父进程终止前运行的一种权宜之计。

3.子进程为挂断信号(SIGHUP)建立信号处理程序。这样就能观察到SIGHUP信号是否已发送到子进程。

4.子进程用kill函数向其自身发送停止信号(SIGTSTP)。这停止了子进程,类似于用终端挂起字符(ctrl+z)停止了一个前台作业。

5.当父进程终止时,该子进程成为了孤儿进程,所以其符进程成为1,也就是init进程ID。同时子进程成为了一个孤儿组的成员。

6.在父进程终止后,进程组成为孤儿进程组,POSIX.1要求向新的孤儿进程组中处于停止状态的每一个进程发送挂断信号

(SIGHUP),接着又向其发送继续信号(SIGCONT)。


程序:

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>

static void sig_hup(int signo){
        printf("SIGHUP revevied, 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){
                perror("fork");
                return -1;
        }else if(pid > 0){
                sleep(5);
                exit(0);
        }else{
                pr_ids("child");
                signal(SIGHUP,sig_hup);
                kill(getpid(),SIGTSTP);
                pr_ids("child");
                if(read(STDIN_FILENO,&c,1) != 1){
                        printf("read error from controlling tty, errno=%d\n",errno);
                }
                exit(0);
        }

        return 0;
}
运行结果:

yan@yan-vm:~/apue$ ./a.out
parent:pid=9154,ppid=9066,pgrp=9154,tpgrp=9154
child:pid=9155,ppid=9154,pgrp=9154,tpgrp=9154
yan@yan-vm:~/apue$ SIGHUP revevied, pid=9155
child:pid=9155,ppid=1,pgrp=9154,tpgrp=9066
read error from controlling tty, errno=5

一开始父进程和子进程在同一个进程组,父进程是前台进程组的首进程,所以前台进程组的进程组ID是父进程组ID。

子进程向自己发送了SIGTSTP信号,所以进程停止,当父进程结束后,子进程称为了孤儿进程,子进程所在的进程组称为了孤儿

进程组,POSIX.1要求向新的孤儿进程组中处于停止状态的每一个进程发送挂断信号(SIGHUP),所以子进程显示接受到了

SIGHUP信号,然后又接收到了继续信号(SIGCONT),子进程继续运行,然后打印了他的进程信息,此时父进程变成了1.

最后调用read,posix规定,在这种情况下,read返回错,并将errno设置为5(EIO)。

要注意的是,父进程终止时,子进程被置入后台进程组中,因为父进程是由shell作为前台作业执行的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值