目录

  1. 进程 ID 类型
  2. 层次化命名空间
  3. 附录

Linux 内核使用 task_struct 数据结构关联所有与进程有关的数据和结构,该数据结构在内核文件的include/linux/sched.h中定义,本篇文章只关注内核中使用了哪些标识符来管理进程

进程 ID 类型

📖内核使用了很多的信息(各种不同的 ID)标识进程,共有如下几种类型:

PID:用来在 PID 命名空间中唯一标识进程的手段,本质上是由内核分配的一个号码,称做进程 ID 号,简称 PID,在使用 fork 或 clone 系统调用时产生的进程均会由内核分配一个新的唯一的 PID 值

PPID:当前进程父进程的 PID 编号

TGID:在一个进程中,如果以 CLONE_THREAD 标志来调用 clone 建立的进程实质上是该进程的一个线程,它们处于一个线程组,该线程组的 ID 叫做 TGID 。处于相同的线程组中的所有线程都有相同的 TGID;线程组组长的 TGID 与其 PID 相同;如果一个进程没有使用线程,则其 TGID 与 PID 也相同

PGID:独立的进程可以组成进程组(使用 setpgrp 系统调用),向所有组内进程发送信号的操作可以简化为向进程组发信号。用管道连接的进程处在同一进程组内。进程组 ID 叫做 PGID ,进程组内的所有进程都有相同的 PGID ,等于该组组长的 PID

SID:几个进程组可以合并成一个会话组(使用 setsid 系统调用),可以用于终端程序设计,会话组中所有进程都有相同的 SID

Session 和 Group 虽然都是管理多个进程的方式,但是两者的意义不同。

session 与终端相关(Control terminal),同一个终端启动的进程默认会在一个 session 里。例如图形界面的终端(比如 GNOME 按ctrl+atl+T呼出的命令行界面),都是虚拟终端(Virtual terminal),他们实质上只有一个终端在真正起作用,输入 w 命令,可以看到所有的 control terminal

group 则是方便管理,比如发送信号,kill 可以一次向一个 group 的进程发送同一个信号,ctrl+z进入后台、bg、fg 都可以对一个 group 的进程起作用。比如ctrl+z可以将一个 group 的进程 stop 暂停运行,fg 可以让一个 group 继续运行

📓同一个 Group 的进程属于同一个 Session,一个 Session 里可以包含多个 Group,使用ps j命令可以显示出以上全部的 ID 信息

层次化命名空间

命名空间(namespace)是为操作系统层面的虚拟化机制提供支撑,目前实现的有六种不同的命名空间,分别为:mount 命名空间、UTS 命名空间、IPC 命名空间、用户命名空间、PID 命名空间、网络命名空间

简而言之,命名空间提供的是对全局资源的一种抽象,通过将资源放到不同的命名空间中,保证资源之间的彼此隔离,这也是如今容器能够实现的根本原因

部分命名空间还存在层次关系,如 PID 命名空间,下图阐述了命名空间的层次关系图

层次化命名空间

上图有四个命名空间,一个父命名空间衍生了两个子命名空间,其中的一个子命名空间又衍生了一个子命名空间。以 PID 命名空间为例,由于各个命名空间彼此隔离,所以每个命名空间都可以有 PID 号为 1 的进程;但是又由于命名空间的层次性,父命名空间知道子命名空间的存在,因此子命名空间终将要映射到父命名空间中去,因此上图中 level 1 中两个子命名空间的六个进程分别映射到其父命名空间的 PID 号 5~10

✨命名空间增大了 PID 管理的复杂性,对于某些进程可能有多个 PID(其自身命名空间的 PID 以及其父命名空间的 PID)。基于此对命名空间中 ID 的分类如下:

全局 ID:在内核本身和初始命名空间中的唯一的 ID,系统中每个进程都对应了该命名空间中的一个 PID,称为全局 ID,该 ID 在整个系统中是唯一的

局部 ID:在某个特定的命名空间中分配的 ID 称为局部 ID,此 ID 在此特定的命名空间是唯一的,但相对于其他命名空间而言,此 ID 可能产能冲突(与其他命名空间中的 ID 重复)

附录

Linux 内核进程管理之进程 ID
PID, PPID, PGID 与 SID