进程组和会话是为了支持 shell 作业控制而引入的概念。
修改进程组 ID 的接口如下:
int setpgid(pid_t pid, pid_t pgid);
这个函数的含义是,找到进程 ID 为 pid 的进程,将其进程组 ID 修改为 pgid,如果 pid 的值为 0,则表示要修改调用进程的进程组 ID。该接口一般用来创建一个新的进程组。
下面三个函数接口含义一致,都是创立新的进程组,并且指定的进程会成为进程组的首进程。
如果参数 pid 和 pgid 的值不匹配,那么 setpgid 函数会将一个进程从原来所属的进程组迁移到 pgid 对应的进程组。
setpgid(0,0)
setpgid(getpid(),0)
setpgid(getpid(),getpid())
setpgid 函数有一些限制:
1)pid 参数必须指定为调用 setpgid 函数的进程或其子进程,不能随意修改不相关进程的进程组 ID,如果违反这条规则,则返回 -1,并置 errno 为 ESRCH。
2)pid 参数可以指定调用进程的子进程,但是子进程如果已经执行了exec函数,则不能修改子进程的进程组 ID。如果违反这条规则,则返回-1,并置 errno 为 EACCESS。
3)在进程组间移动,调用进程,pid 指定的进程及目标进程组必须在同一个会话之内。这个比较好理解,不加入公司(会话),就无法加入公司下属的部门(进程组),否则就是部门要造反的节奏。如果违反这条规则,则返回-1,并置 errno 为 EPERM。
4)pid 指定的进程,不能是会话首进程。如果违反这条规则,则返回 -1,并置 errno 为 EPERM。
有了创建进程组的接口,新创建的进程组就不必继承父进程的进程组 ID 了。