一、进程组
每个进程除了有一个进程ID外,还属于一个进程组(process group)。
进程组是一个或者多个进程的集合。每个进程组中有一个唯一的进程组ID。函数getpgrp返回调用进程的进程组ID:
#include <sys/types.h>
#include <unistd.h>
pid_t getpgrp(void)
每个进程组有一个组长进程,组长进程的标识是其进程ID等于其进程组ID。
进程组组长可以创建一个进程组,创建该组中的进程并终止。只要在某个进程组中有一个进程存在,在该进程组就存在,与其组长进程是否终止无关。从进程组创建开始到其中最后一个进程离开为止的时间区间称为进程组的生存期。某个进程组中的最后一个进程可以终结,也可以加入另外一个进程组。
通过调用setpgid可以将一个进程加入现存的一个进程组,或者创建一个新的进程组:
#include <sys/types.h>
#include <unistd.h>
int setpgid(pid_t pid,pid_t pgid);
----------------------------------成功返回0,出错返回-1
该函数将进程组ID为pid的进程的进程组ID设置为pgid。若pid=pgid,则pid进程为该进程组组长。
会话期(session)是一个或者多个进程组的集合。
#include <sys/types.h>
#include <unistd.h>
pid_t setsid(void);
----------------------------成功返回进程组ID,失败返回-1
调用该函数的进程如果为进程组长,则返回-1,否则该函数新建一个会话:
Linux 内核通过维护会话和进程组而管理多用户进程。每个进程是一个进程组的成员,而每个进程组又是某个会话的成员。一般而言,当用户在某个终端上登录时,一个新的会话就开始了。进程组由组中的领头进程标识,领头进程的进程标识符就是进程组的组标识符。类似地,每个会话也对应有一个领头进程。
同一会话中的进程通过该会话的领头进程和一个终端相连,该终端作为这个会话的控制终端。一个会话只能有一个控制终端,而一个控制终端只能控制一个会话。用户通过控制终端,可以向该控制终端所控制的会话中的进程发送键盘信号。
同一会话中只能有一个前台进程组,属于前台进程组的进程可从控制终端获得输入,而其他进程均是后台进程,可能分属于不同的后台进程组。