线程与进程
进程与线程的区别
- 进程是资源分配的最小单元。
- 线程是执行与调度的最小单元。
- 一个进程由一个或多个线程组成。
- 进程之间资源相互独立,但同一进程下的各个线程之间共享程序的内存空间(包括代码段、数据集、堆等)以及进程级的资源(如打开文件和信号)。
- 进程内的线程在其它进程不可见。
PID 与 TID
- PID: 进程 ID。
- TID: 线程 ID。进程 PID 和它的主线程的 TID 总是相同的。
- TGID: 线程组 leader 的 PID。
- PGID: 进程组 leader 的 PID。一个进程组包含多个进程。进程组中所有进程都有相同的 PGID。
- SID: 会话 ID (session ID)。一个会话组包含多个进程组,会话组中所有进程都有相同的 SID。
- Pthread ID: pthread 库提供的 ID。在同一个进程中是唯一的,不同进程不唯一。
- TPGID: 控制终端的 PGID。由控制终端修改,用于指示当前前台进程组。
USER VIEW: <-- PID 43 --> <---------- PID 42 ----------->
┌──────────┐
Fork │ pid=42 │ New Thread
─┌────────│ tgid=42 │───────────┐
▼ └──────────┘ ▼
┌──────────┐ ┌──────────┐
│ pid=43 │ │ pid=44 │
│ tgid=43 │ │ tgid=42 │
└──────────┘ └──────────┘
KERNEL VIEW: <-- PID 43 --> <--- PID 42 ---> <-- PID 44 -->
线程
- 内核空间:内核线程 (Kernel-Level Thread) 与轻量级进程 (Light Weight Process)
- 用户空间:用户线程
进程上下文
「待补充」
进程控制块
进程控制块 (PCB: Process Control Block) 是进程存在的唯一标识。 每个进程有且仅有一个 PCB。
PCB 一般包括:
1.程序ID(PID、进程句柄):它是唯一的,一个进程都必须对应一个PID。PID一般是整形数字 2.特征信息:一般分系统进程、用户进程、或者内核进程等 3.进程状态:运行、就绪、阻塞,表示进程现的运行情况 4.优先级:表示获得CPU控制权的优先级大小 5.通信信息:进程之间的通信关系的反映,由于操作系统会提供通信信道 6.现场保护区:保护阻塞的进程用 7.资源需求、分配控制信息 8.进程实体信息,指明程序路径和名称,进程数据在物理内存还是在交换分区(分页)中 9.其他信息:工作单位,工作区,文件信息等
线程上下文
「待补充」
多线程共享资源
- 堆:由于堆是在进程空间中开辟出来的,所以它是理所当然地被共享的;
- 全局变量:它是与具体某一函数无关的,所以也与特定线程无关;因此也是共享的
- 静态变量:虽然对于局部变量来说,它在代码中是“放”在某一函数中的,但是其存放位置和全局变量一样,存于堆中开辟的.bss和.data段,是共享的
- 文件等公用资源:这个是共享的,使用这些公共资源的线程必须同步。
- 地址空间
- 子进程、闹铃、信号及信号服务程序、记账信息
- 进程代码段
单线程独享资源
- 栈
- 寄存器
- 程序计数器
- 状态字
- 线程优先级
- 错误返回码
上下文切换
CPU 亲和性 (CPU Affinity)
Linux 内核进程调度器具备软 CPU 亲和性,进程/线程通常不会在处理器之间频繁迁移。 Linux 内核也提供系统调用,强行将进程/线程绑定到指定的 CPU 核运行。
绑定到指定的 CPU 核有利于:
- 提高 CPU Cache 命中率。
- 进程需要高密度的计算,不希望被频繁调度
还可以用 taskset
命令查询或者设置指定进程的亲和性掩码。