进程关系和作业控制

本文介绍了进程组、会话及控制终端的概念,探讨了如何通过函数操作进程组ID和会话,解释了作业控制机制,并讨论了孤儿进程组的行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.进程组

     进程组是一个或多个进程的集合,有个唯一的进程组ID。每个进程组有一个组长进程,其进程ID等于进程组ID。进程组的生命期从创建开始,到最后一个进程离开为止。

      获取和设置进程组ID的函数:

(1)返回调用进程的进程组ID:

    pid_t getpgrp(void);

(2)返回进程pid的进程组ID:

    pid_t getpgid(pid_t pid);      //若pid = 0,与getpgrp函数等效

(3) 加入/创建一个进程组:

    int setpgid(pid_t pid, pid_t pgid);      //将pid进程的进程组ID设置为pgid;若pid = pgid,pid进程变为进程组组长;如果pid = 0,则使用调用者的进程ID;若pgid = 0,用pid进程的进程ID作为进程组ID。   

    一个进程只能为自身或其子进程设置进程组ID。在fork子进程后,如果要设置子进程的进程组ID,为避免出现竞争,父进程要设置子进程的进程组ID,子进程也要设置自身的进程组ID。

2. 会话

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

      建立一个新会话:pid_t setsid(void);

      如果调用setsid的进程不是一个进程组的组长,则创建一个新会话;若进程组组长调用该函数,则返回出错,为避免该情况,通常先调用fork,然后父进程终止,子进程继续,子进程继承父进程的进程组ID,而其进程ID是新分配的,如此则可以保证子进程不是一个进程组的组长。

      一个进程创建一个新会话后:该进程变成新会话的会话首进程(此时该进程是新会话中的唯一进程);该进程成为一个新进程组的组长进程;该进程组没有控制终端。

       返回会话首进程的进程组ID:

       pid_t getsid(pid_t pid);       //若pid=0,返回调用进程的会话受进程的进程组ID;pid不属于调用者所属的会话则无法获取。

3. 控制终端

    一个会话可以有一个控制终端;与控制终端连接的会话首进程为控制进程;会话中的进程组可分为一个前台进程组和一个或多个后台进程组,前台进程组可以接收控制终端的输入和信号。控制终端的挂断信号会发送到控制进程。

4. 作业控制

      一个作业是几个进程的集合,通常是一个进程管道;可以在前台或后台启动一个作业,命令行后加空格和&,则为后台作业(如:pr *.c | lpr &);前台进程组可以收到3个终端发送的信号:中断(Ctrl+C,SIGINT),退出(Ctrl+\,SIGQUIT),挂起(Ctrl+Z,SIGTSTP);

      若后台作业试图读终端,终端驱动程序向后台作业发送SIGTTIN信号停止该后台作业,将后台作业转为前台就可以读终端;类似,若后台作业试图写终端,会产生SIGTTOU信号。

5. 孤儿进程组

      定义:孤儿进程组的每个成员的父进程要么是该组的一个成员,要么不是该组所属会话的成员;

      不是孤儿进程组的条件:该组中有一个进程,其父进程在属于同一会话的另一个组中(有机会重启该组中停止的进程)。

   若进程组成为孤儿进程组,POSIX.1要求向孤儿进程组中处于停止状态的每个进程发送挂断信号(SIGHUP),接着又向其发送继续信号(SIGCONT)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值