1、每个进程除了有一个进程ID外,还属于一个进程组。
进程组是一个或多个进程的集合,通常它们是在同一作业中结合起来的。
每个进程组有一个唯一的进程组ID(正整数、pid_t类型)。
2、函数getpgrp返回调用进程的进程组ID
#include <unistd.h>
pid_t getpgrp(void);
返回值:调用进程的进程组ID
函数getpgid返回进程组ID
#include <unistd.h>
pid_t getpgid(pid_t pid);
若出错返回-1;
若pid是0,返回调用进程的进程组ID(所以getpgid(0)等价于getpgrp())
3、每个进程组有一个组长进程,组长进程的进程组ID=其进程ID。
组长可以建立一个进程组、创建该组中的进程,然后终止,只要进程组中有一个进程存在,该进程组就存在,与组长是否终止无关,组中最后一个进程可以终止也可以转移到另一个进程组。
4、进程调用setpgid可以加入一个现有的进程组或者创建一个新进程组
#include <unistd.h>
int setpgid(pid_t pid,pid_t pgid);
返回值:若成功,返回0,出错返回-1;
一个进程只能为它自己或者它的子进程设置进程组ID,setpgid函数将pid进程的进程组ID设置为pgid,如果这两个参数相等,则由pid指定的进程变成进程组组长(等效新建一个进程组),如果pid等于0,则使用调用者的进程ID,如果pgid为0,则由pid指定的进程ID用作进程组ID。
5、会话(session)
会话是一个或者多个进程组的集合。进程调用setsid函数建立一个新会话:
#include <unistd.h>
pid_t setsid(void);
返回值:若成功,返回进程组ID,出错返回-1.
调用此函数的进程不能是一个进程组的组长,否则会出错,成功调用后:
a.该进程变成新会话的会话首进程(session leader,会话首进程是创建该会话的进程),该进程是会话中唯一的进程。
b.该进程成为一个新进程组的组长进程,新进程组ID是该进程ID。
c .该进程没有控制终端(如果有也被切断)。
getsid函数返回会话首进程的进程组ID;
#include <unistd.h>
pid_t getsid(pid_t pid);
返回pid进程所在会话的会话首进程的进程组ID,如pid=0,则返回调用进程的会话首进程的进程组ID。
6、控制终端
一个会话可以有一个控制终端,通常是终端设备。建立与控制终端连接的会话首进程被称为控制进程。
一个会话中的几个进程组可以被分成一个前台进程组和一个或多个后台进程组。
无论何时键入终端的中断键(Delete或Ctrl+c),都会将中断信号发送至前台进程组的所有进程。