一、进程组

1. 进程组概述

进程组是一个或多个进程的集合。进程组随进程组首进程创建,进程组的PGID为首进程ID。进程组的生命周期从首进程的创建开始,到进程组内的最后一个进程结束或离开而结束。

2. 进程组API

(1)获取本进程进程组ID,该函数一定能够成功返回。

#include <unistd.h>
pid_t getpgrp(void);
功能:获取本进程进程组ID
参数:void
返回值:本进程进程组ID

(2)获取指定进程的进程组ID。

#include <unistd.h>
pid_t getpgid(pid_t pid);
功能:获取指定进程进程组ID
参数:进程id
返回值:
	当pid==0时,作用和getpgrp();相同
	当pid!=1时,成功返回进程组ID,失败返回-1

(3)设置指定进程的进程组PGID。

#include  <unistd.h>
int setpgrp(pid_t pid, pid_t pgid);
功能:修改指定进程进程组ID
参数:
	pid:进程pid
	pgid:进程组PGID
返回值:
	成功返回0,失败返回-1

二、会话

1.会话概述

会话是一个或多个进程组的集合。会话组的创建是随着会话首进程的创建而创建的,会话的SID为首进程的ID。

一个会话中的所有进程共享单个控制终端,控制终端会在会话首进程首次打开一个终端设备时创建。

在任意时刻,会话中的某个进程组会成为前台进程组,其他程序成为后台进程组。只有前台进程组能够从控制终端读取输入:普通的字符输入或信号终端字符。当用户在控制终端中输入其中一个信号生成终端字符之后,该信号会被发送到前台进程组中的所有成员。`当到控制终端的连接建立起来(即打开)之后,会话首进程会成为该终端的控制进程。

会话和进程组的主要用途是用于 shell 作业控制。

终端、进程组、会话之间的关系如下图:
在这里插入图片描述

2.会话API

(1) 获取进程所属的会话ID

#include <unistd.h>
pid_t getsid(pid_t pid);
功能:获取进程所属的会话ID
参数:
    pid:进程号,pid为0表示查看当前进程session ID。如果pid为0,会返回调					  用进程的会话ID
返回值:
    成功:返回调用进程的会话ID
    失败:-1

(2)设置会话ID

#include <unistd.h>
pid_t setsid(void);
功能:
    创建一个会话,并以自己的ID设置进程组ID,同时也是新会话的ID。
参数:无
返回值:
    成功:返回调用进程的会话ID
    失败:-1

setsid()按照下列步骤创建一个新会话

  • 调用进程成为新会话的首进程和该会话中新进程组的首进程。调用进程的进程组 ID和会话 ID 会被设置成该进程的进程 ID。
  • 调用进程没有控制终端。所有之前到控制终端的连接都会被断开。

如果调用进程是一个进程组首进程,那么 setsid()调用会报出 EPERM 错误。避免这个错误发生的最简单的方式是执行一个 fork()并让父进程终止以及让子进程调用 setsid()。由于子进程会继承其父进程的进程组 ID 并接收属于自己的唯一的进程 ID,因此它无法成为进程组首进程。

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐