《unix环境高级编程》--- 进程关系

会话是一个或多个进程组的集合。

作业控制

yjp@yjp-VirtualBox:~$ cat > temp.foo &            在后台启动,但从标准输入读,收到SIGTTIN信号
[1] 2478
yjp@yjp-VirtualBox:~$                             键入回车

[1]+  Stopped                 cat > temp.foo    停止后台作业
yjp@yjp-VirtualBox:~$ fg %1                       使1号作业成为前台作业
cat > temp.foo                                  shell告诉我们哪个作业在前台
hello world                                     键入一行
yjp@yjp-VirtualBox:~$ cat temp.foo                检查该行送入文件
hello world
yjp@yjp-VirtualBox:~$ 
yjp@yjp-VirtualBox:~$ ps -o pid,ppid,pgrp,session,tpgid,comm
  PID  PPID  PGRP  SESS TPGID COMMAND
 2435  2429  2435  2435  2913 bash
 2913  2435  2913  2435  2913 ps                ps是组长进程,此进程组是前台进程组
yjp@yjp-VirtualBox:~$ ps -o pid,ppid,pgrp,session,tpgid,comm &  
[1] 2918
yjp@yjp-VirtualBox:~$   PID  PPID  PGRP  SESS TPGID COMMAND   成为后台进程组
 2435  2429  2435  2435  2435 bash
 2918  2435  2918  2435  2435 ps

创建一个孤儿进程组

#include "apue.h"
#include <errno.h>

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 */
        /*
          若父进程退出导致进程组成为孤儿进程组,且该进程组中有进程处于停止状态(收到SIGSTOP或SIGTSTP信号),
          SIGHUP信号会被发送到该进程组中的每一个进程。
        */
        kill(getpid(), SIGTSTP); /* stop ourself */
        pr_ids("child");
        if(read(STDIN_FILENO, &c, 1) != 1) /* prints only if we're continued */
        {
            printf("read error from controlling TTY, errno = %d\n", errno);
            exit(0);
        }
    }
    return 0;
}   

这里写图片描述
子进程的父进程ID没有变成1,而是1327 ?
子进程调用pr_ids后,程序试图读标准输入。后台进程组试图读控制终端时,则对该后台进程组产生SIGTTIN。但此时已是孤儿进程组,
如果内核用此信号停止它,则此进程组中的进程就再也不会继续。这时read返回出错,并将errno设置为EIO,即5.
父进程终止时,子进程被植入后台进程组,因为父进程时由shell作为前台作业执行的。

猜你喜欢

转载自blog.csdn.net/u012319493/article/details/80411552