Linux服务器程序规范 - 进程间关系

进程组

Liunx下每个进程都隶属于一个进程组,因此它们除了PID,还有进程组ID(PGID),我们可以用如下函数来获取指定进程的PGID:

#include <unistd.h>
pid_t getpgid(pid_t pid);

该函数成功时返回进程pid所属进程组PGID,失败则返回-1并设置errno。

每个进程组都有一个首领进程,其PGID和PID相同。进程组将一直存在,直到其中所有进程都退出,或者加入到其他进程组。

下面这个函数用来设置PGID:

#include <unistd.h>
int setpgid(pid_t pid, pid_t pgid);

这个函数将PID为pid的进程的PGID设置为pgid。

  • 如果pid和pgid相同,则由pid指定的进程将被设置为进程组首领
  • 如果pid为0,则表示设置当前进程的PGID为pgid
  • 如果pgi为0,则使用pid作为目标PGID。

setpgid调用成功时返回0,失败返回-1并设置errno。

这里需要注意的是:

一个进程只能设置自己或者其子进程的PGID。并且,当子进程调用exec系列函数后,我们也不能再在父进程中对它设置PGID。

会话

一些有关联的进程组将形成一个会话(session)。下面的函数用于创建一个会话:


#include <unistd.h>
pid_t setsid(void);

这个函数不可以由进程组的首领进程调用,否则将产生一个错误。对于非组首领的进程,调用该函数不仅创建新会话,而且有如下额外效果:

  • 调用进程会成为会话的首领,此时该进程是新会话的唯一成员
  • 新建一个进程组,其PGID就是调用进程的PID,调用进程成为该组的首领
  • 调用进程将甩开终端(如果有的话)

该函数成功时返回新的进程组的PGID,失败则返回-1并设置errno。

Linux进程并未提供所谓会话ID(SID)的概念,但Linux系统认为它等于会话首领所在的进程组PGID,并且提供如下函数来读取SID:

#include <unistd.h>
pid_t getsid(pid_t pid);

用ps命令查看进程关系



我们在bash shell下执行ps和less命令,所以ps和less命令的父进程是bash命令,我们可以从PPID(父进程PID)一列可以看出。这三条命令创建了一个会话ID(SID是12308)和两个进程组ID(PGID分别是12308和12316)。bash命令的PID、PGID和SID都相同,很明显它既是会话的首领也是组12308的首领。ps命令则是组12316的首领,因为其PID也是12316。

原文链接:,转发请注明来源!