进程与线程
进程与线程是操作系统进行资源分配和调度的基本单位。本节介绍二者的定义、表示方式以及在用户态与内核态下的运行差异。
进程
进程(Process)是程序在某数据集合上的一次动态执行过程,是系统进行资源分配的基本单位。每个进程拥有独立的地址空间、代码、数据、堆栈以及一组系统资源(如打开的文件、信号量等)。
操作系统为每个进程维护一个 PCB(Process Control Block,进程控制块),用于保存进程状态、程序计数器、寄存器、内存指针、IO 信息等。典型的进程状态包括 new、ready、running、waiting、terminated。
线程
线程(Thread)是进程内的执行流,是 CPU 调度的基本单位。同一个进程内的多个线程共享进程的地址空间、堆、全局变量和打开的文件,但各自拥有独立的栈和寄存器上下文。
线程相比进程具有更小的创建/销毁开销和更快的上下文切换速度,但由于共享内存,需要额外的同步机制来避免竞态条件。
用户态与内核态
CPU 通常提供两个特权级:用户态(user mode)与内核态(kernel mode)。用户态下不能直接访问硬件或敏感资源;系统调用、异常和中断会使 CPU 切换到内核态,由操作系统代表进程完成特权操作。
用户进程 ──系统调用──> 内核态 ──返回──> 用户进程继续执行
协程
协程(Coroutine)是一种由程序自身调度的轻量级执行单位,无需操作系统介入。协程在用户态完成上下文切换,占用资源极少,适合高并发 IO 场景。Go 语言的 goroutine、Kotlin 的 suspend 函数、Python 的 asyncio 都属于协程模型。
进程与线程对比
| 维度 | 进程 | 线程 |
|---|---|---|
| 资源占用 | 独立地址空间,开销大 | 共享地址空间,开销小 |
| 切换成本 | 高(需切换页表等) | 低(仅切换栈与寄存器) |
| 通信方式 | IPC(管道、套接字等) | 共享内存 + 同步原语 |
| 隔离性 | 强,互不影响 | 弱,需同步 |
| 典型代表 | fork 出的子进程 | pthread、Java Thread |