进程与线程的资源
2025/9/3...大约 6 分钟OS
我们常说,在操作系统中,进程是资源分配的基本单位,它代表一个程序独立的执行环境,这通常包含了进程的地址空间、系统资源和执行上下文。而线程,它是进程内的执行单元,是操作系统调度的最小单位。线程通常共享所属进程的资源,但它也拥有一些独立的资源。当然,这里的线程主要指内核线程,用户态线程(如协程)并不被操作系统感知,但核心概念类似。另外,线程依赖于进程,不能独立存在。线程共享进程的大部分资源,但有自己的执行上下文。
简单理解,进程是操作系统为不同运行中的程序划分资源的一种手段,而线程是操作系统的基本调度单位,是并行编程中的核心设计。
按照进程和线程的资源是否可以进行共享的维度,可以作如下分类:
- 进程独占资源:进程独立拥有的资源,不与其他进程共享。
- 进程共享资源:通过特定机制(如共享内存、管道、消息队列等)在多个进程间共享的资源。
- 线程独有资源:每个线程独立的资源,用于独立执行。
- 线程共享资源:线程与所属进程的其他线程共享的资源(因为线程是进程的子单元)。
进程使用的资源
进程作为资源分配的基本单位,拥有以下关键资源:
资源类型 | 英文名称 | 说明 |
---|---|---|
地址空间 | Memory Address Space | 包括代码段(text)、数据段(data)、堆(heap)和栈(stack)。这是进程隔离的核心,确保不同进程的内存互不干扰 |
文件描述符表 | File Descriptors | 打开的文件、套接字、管道等I/O资源的索引表 |
信号处理程序 | Signal Handlers | 定义进程如何响应各种信号(如SIGINT、SIGTERM等) |
进程标识 | Process ID (PID) | 进程的唯一标识符,包括PID和父进程ID(PPID) |
用户和组标识 | User ID, Group ID | 用于系统权限控制和资源访问管理 |
环境变量 | Environment Variables | 如PATH、HOME等,影响进程的运行环境 |
工作目录 | Current Working Directory | 进程执行时的当前目录路径 |
系统资源句柄 | System Resource Handles | 如设备、进程间通信(IPC)机制(共享内存、信号量、消息队列)等的引用 |
虚拟内存映射 | Virtual Memory Mapping | 包括页表和内存映射信息,用于内存管理和访问控制 |
CPU时间和调度信息 | CPU Time and Scheduling Info | 进程整体的优先级、调度策略和CPU使用统计 |
进程的资源分类如下:
资源类别 | 独占资源(每个进程单独拥有) | 共享资源(可由多个进程共享) | 说明 |
---|---|---|---|
内存 | - 虚拟地址空间 - 代码段、数据段、堆、栈 | - 共享内存(Shared Memory Segment) | 独占内存保证隔离;共享内存是最快的 IPC 方式,需要同步机制 |
CPU 相关 | - 程序计数器(PC) - 寄存器上下文 - 线程栈 | - 无(CPU 时间片由调度器分配,不是真正的共享) | CPU 状态独立保存,进程切换时上下文切换 |
文件/IO | - 文件描述符表(每个进程自己的副本) | - 打开的文件(指向相同 inode 的文件描述符可被不同进程共享) - 管道(Pipe) - 命名管道(FIFO) | 文件表项可引用相同底层文件;管道是单向通信机制 |
操作系统对象 | - 进程控制块(PCB) - 信号处理表 | - 消息队列 - 信号量(Semaphore) - 套接字(Socket) | PCB 独立;IPC 对象由内核维护,可被多个进程访问 |
设备 | - 独占的设备上下文(如果进程单独占用某个设备) | - 共享设备(多个进程可同时访问打印机、磁盘等,通过驱动和内核仲裁) | 内核提供访问仲裁与同步 |
其他 | - 环境变量副本 - 当前工作目录 | - 映射文件(Memory-mapped file) - 共享库(Shared Library) | 共享库代码段通常可被多个进程同时映射到内存 |
线程使用的资源
操作系统不会为线程独立分配太多种类的资源,线程作为进程内的一个内部存在,更多的是使用其所在进程拥有的绝大部分资源,进程内的所有线程遵守这个规则,对进程内的资源进行共享使用,这也就是为什么线程间通信比进程间通信更加容易。
但是,我们知道线程是操作系统调度的最小单位,为了完成线程间切换这个动作,线程必须有自己独立的上下文,这样才能保证被中断线程的恢复。
不同线程间的共享资源(与进程及其他线程共享):
- 地址空间(代码、数据、堆):所有线程可见,可读写共享变量(需注意同步);
- 文件描述符表:线程可共享打开的文件;
- 信号处理程序:通常进程级,但某些信号可线程特定;
- 用户/组标识、环境变量、工作目录:线程继承进程的;
- 系统资源句柄:如共享内存;
每个线程用于的独有资源(每个线程独立):
- 线程标识(Thread ID, TID);
- 栈(Stack):用于函数调用和局部变量,防止线程间栈溢出干扰;
- 寄存器上下文(Registers):包括程序计数器(
PC
)、栈指针(SP
)、通用寄存器,用于线程切换; - 线程局部存储(Thread-Local Storage, TLS):如
errno
在多线程中的线程特定副本; - 调度属性:线程优先级、CPU 亲和性、栈大小等;
- 信号掩码(Signal Mask):线程可有独立的信号屏蔽设置;
- 错误代码:如
pthread
中的线程特定错误;
总结
下面是进程和线程拥有的资源及其共享范围对比:
资源类型 | 进程(独立拥有) | 线程(共享或独有) | 说明 |
---|---|---|---|
地址空间 | 独立地址空间 | 共享进程的地址空间 | 进程隔离,线程共享导致潜在竞争 |
栈 | 进程主线程的栈 | 每个线程独立栈 | 线程栈用于本地执行上下文 |
文件描述符 | 独立表 | 共享进程的表 | 线程可并发读写同一文件 |
信号处理 | 进程级处理程序 | 共享,但可线程特定掩码 | 大多数信号发给进程 |
标识符 | PID 、PPID | TID | TID 在进程内唯一 |
用户/组ID、环境变量 | 独立 | 共享 | 权限和环境一致 |
工作目录 | 独立 | 共享 | chdir () 影响整个进程 |
寄存器上下文 | 进程级(主线程) | 每个线程独立 | 用于上下文切换 |
线程局部存储 (TLS) | 不适用 | 每个线程独立 | 存储线程私有数据 |
调度属性 | 进程优先级 | 线程优先级(可独立) | 线程可有不同调度策略 |