进程,进程组,会话,线程,父子进程,线程组,孤儿进程,兄弟进程,兄弟线程
1.核心概念逐个解释
- 进程(Process)
操作系统资源分配的最小单位。拥有独立的虚拟地址空间、打开文件表、信号处理等资源。进程是程序的一次执行实例。 - 线程(Thread)
操作系统CPU 调度的最小单位。线程依附于进程,共享进程的地址空间和资源,但拥有独立的栈、寄存器、程序计数器。一个进程至少包含一个线程(主线程)。 - 父子进程
- 父进程通过 fork() 创建子进程。
- 子进程继承父进程的部分属性(环境变量、文件描述符、信号处理等),但拥有独立的 PID 和地址空间(写时复制 COW)。
- 子进程终止时,父进程应通过 wait() 回收其资源,否则子进程变为僵尸进程。
- 兄弟进程
- 由同一父进程创建的多个子进程互为兄弟进程。
- 兄弟进程之间彼此独立,无直接层级关联,不共享地址空间,通信需通过 IPC。
- 孤儿进程
- 父进程先于子进程终止,子进程失去父进程。
- 操作系统会将孤儿进程的 PPID 重新设置为 init 进程(PID 1)或 systemd 收养。
- 孤儿进程不是异常状态,被收养后可正常执行直至终止。
- 进程组(Process Group)
- 一个或多个进程的集合,用于批量信号管理。
- 每个进程组有一个进程组 ID(PGID),通常等于组长进程的 PID。
- 同一管道线(如 ls | grep | wc)中的命令通常属于同一进程组。
- 向进程组发送信号(如 kill -9 -pgid)可同时影响组内所有进程。
- 会话(Session)
- 一个或多个进程组的集合,用于终端控制。
- 会话首进程(Session Leader)通常是登录 Shell。
- 一个会话可包含一个前台进程组和多个后台进程组。
- 终端断开会向会话首进程发送 SIGHUP,导致会话内进程默认终止。
- 线程组(Thread Group)
- Linux 特有的概念。同一进程内的所有线程属于同一个线程组。
- 线程组 ID(TGID)等于主线程的 PID。用户态调用 getpid() 实际返回的是 TGID。
- 线程组内的线程通过 clone() 创建,共享 mm_struct(地址空间)、files_struct(文件表)等。
- kill -9 pid 会终止整个线程组(即整个进程)。
- 兄弟线程
- 同一进程内的多个线程互为兄弟线程。
- 它们共享进程的地址空间、全局变量、堆、文件描述符等,是最紧密的协作关系。
- 通信成本极低(直接内存读写),但需通过锁、原子操作等机制同步。
2.关系总览
┌─────────────────────────────────────────────────────────────┐ │ 操作系统 │ │ ┌───────────────────────────────────────────────────────┐ │ │ │ 会话(Session) │ │ │ │ ┌─────────────────┐ ┌─────────────────────────┐ │ │ │ │ │ 进程组1│ │ 进程组2│ │ │ │ │ │ ┌───────────┐ │ │ ┌───────────┐ │ │ │ │ │ │ │ 进程 A │ │ │ │ 进程 B │ │ │ │ │ │ │ │ ┌───────┐ │ │ │ │ ┌───────┐ │ │ │ │ │ │ │ │ │ 线程1│ │ │ │ │ │ 线程1│ │ │ │ │ │ │ │ │ ├───────┤ │ │ │ │ └───────┘ │ │ │ │ │ │ │ │ │ 线程2│ │ │ │ └───────────┘ │ │ │ │ │ │ │ └───────┘ │ │ └─────────────────────────┘ │ │ │ │ │ └───────────┘ │ │ │ │ │ └─────────────────┘ │ │ │ └───────────────────────────────────────────────────────┘ │ │ │ │ 进程 A 和进程 B:无亲缘关系,通过 IPC 通信 │ │ 进程 A 的线程1/2:兄弟线程,共享地址空间 │ └─────────────────────────────────────────────────────────────┘3.层级关系与归属
| 层级 | 组成单位 | 关键标识 | 作用 |
|---|---|---|---|
| 会话 | 一个或多个进程组 | SID(会话 ID) | 终端控制、作业管理 |
| 进程组 | 一个或多个进程 | PGID(进程组 ID) | 信号批量分发 |
| 进程 | 一个或多个线程 | PID(进程 ID) | 资源分配、地址空间隔离 |
| 线程组 | 一个或多个线程 | TGID = 主线程 PID | Linux 内核对线程的归类 |
| 线程 | 执行单元 | TID(线程 ID) | CPU 调度 |
4.Linux 中的 ID 辨析
在 Linux 中,这些概念通过不同的 ID 区分:
- PID:进程/线程的唯一标识。对主线程而言,PID = TGID;对子线程而言,PID 是其独立 TID。
- TGID:线程组 ID,getpid() 的返回值。同一进程内所有线程 TGID 相同。
- PGID:进程组 ID,getpgrp() 的返回值。
- SID:会话 ID,getsid() 的返回值。
- PPID:父进程 ID。