linux 进程线程中的各种 id

linux 进程与线程中的各种 id

操作系统中有进程和线程的概念, 分别是进程对应 pid(process id), 线程对应 tid(thread id). 而在 linux 操作系统中, 由于一些历史遗留原因, linux 中的 pid 其实是 LWP tid, 而 tgid 才是操作系统意义上的 pid.

内核中的名称解释系统调用
tgid线程组 ID, 进程 IDgetpid()
pid线程 IDgettid()
pgid进程组 IDgetpgid()
ppid父进程 PIDgetppid()
sidsession IDgetsid()
  • pid 与 tgid

内核中的 pid 表示的是每个 task_struct 都有的全局唯一的线程 id, 无论进程线程都有.

进程与线程是一对多的关系, 即多个线程属于一个进程, 其中进程(主线程)的 pid 等于自己的 tgid. 而线程的 tgid 则是线程组中的主线程的 pid, 线程的 pid 是自己的线程 id.

ps -Lf为例, 注意下面的 PID 实际上是 tgid, LWP 才是内核的 pid

1
2
3
4
5
6
7
8
9
ᐅ ps -Lf
UID          PID    PPID     LWP  C NLWP STIME TTY          TIME CMD
lomot     753661  753660  753661  0    1 Sep21 pts/12   00:00:48 -zsh
lomot     753690       1  753690  0    1 Sep21 pts/12   00:00:00 -zsh
lomot     753698  753690  753698  0   17 Sep21 pts/12   00:00:02 .../gitstatusd-linux-x86
lomot     753698  753690  753699  0   17 Sep21 pts/12   00:00:00 .../gitstatusd-linux-x86
lomot     753698  753690  753700  0   17 Sep21 pts/12   00:00:00 .../gitstatusd-linux-x86
lomot     753698  753690  753701  0   17 Sep21 pts/12   00:00:00 .../gitstatusd-linux-x86
lomot     773073  753661  773073  0    1 01:59 pts/12   00:00:00 ps -Lf

上面的 PID 是内核中的 tgid, LWP 是内核中的 pid, PPID 是父进程 id. 可以看到 753690 号进程 fork 出了 753698 号进程, 然后 753698 号进程创建了多个线程(LWP), 每个线程 id 都不相等, 但线程的 tgid 都等于第一个进程的 pid.

  • pgid 与 sid

直接看ps -lj

1
2
3
4
5
6
ᐅ ps -lj
F S   UID     PID    PPID    PGID     SID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
0 S  1001  753661  753660  753661  753661  0  80   0 -  4743 sigsus pts/12   00:00:49 zsh
1 S  1001  753690       1  753689  753661  0  80   0 -  3170 sigsus pts/12   00:00:00 zsh
0 S  1001  753698  753690  753689  753661  0  80   0 -  1131 poll_s pts/12   00:00:02 gitstatusd-linu
0 R  1001  773823  753661  773823  753661  0  80   0 -  2202 -      pts/12   00:00:00 ps

可以看到 753690 与 753698 共属一个进程组, 而 753661, 753690, 753698, 773823 则是共属与一个 session 组