首页 > 代码库 > 进程组和会话
进程组和会话
进程组
进程组是指一个或多个进程的集合。通常与一个作业相关联,可以接收来自同一终端的信号。每个进程组有一个唯一的进程组ID,它类似于进程ID,是一个正整数(其实就是组长进程的进程ID)。可以通过函数获得
#include<unistd.h>
pid_t getpgrp(void);
进程组都有一个组长,组长进程的标识是其进程组ID等于进程ID。
组长可以创建一个组长进程组,创建该进程组的进程,然后终止。进程存在于组长存在没必要关系,只要进程组有一个进程存在,则进程组就存在。进程组生命周期为组长创建到最后一个进程离开为止。进程组中最后一个进程可以终止,或者转移到另一个进程组中。
可以通过下面函数加入一个进程组或创建一个进程组:
#include<unistd.h>
int setpgid(pid_t pid, pit_t pgid);
一个进程只能为它自己或自己的子进程设置进程组ID,在它的子进程调用了exec函数后,它就不能再改变该子进程的进程组ID了。
在大多数作业控制的shell中,在fork之后调用setpgid函数,使父进程设置其子进程的进程组ID,并且使子进程设置其自己的进程组ID。如果不这样做,那么fork之后,由于父、子进程运行先后次序的不确定,会造成在一段时间内(父、子进程只运行了其中一个)子进程组员身份的不确定(取决于哪个进程先执行),这就产生了竞争条件。
会话(session)
会话是一个或多个进程组的集合。shell的管道线将几个进程编成一组。
proc1 | proc2 &
proc3 | proc4 | proc5
编成的会话如下图:
进程调用setsid函数建立一个新会话
#include<unistd.h>
pid_t setsid(void);
如果调用此函数的进程不是一个进程组的组长,则此函数会创建一个新会话,结果将发生下面3件事:
1、该进程变成新会话首进程。此时,该进程是新会话的唯一的进程。
2、该进程成为一个新进场组的组长进程。新进程组的ID是该调用进程的进程ID。
3、该进程没有控制终端。如果有,在调用后,这种联系也会被中断。
如果该进程是一个进程组的组长进程,则此函数返回出错。为了保证不会发生这种情况,通常先调用fork,然后使其父进程终止,而子进程则继续。
进程组和会话