进程与线程

返回计算机基础

进程是操作系统资源分配的基本单位,线程是 CPU 调度的基本单位。理解两者的区别是掌握并发编程的前提。


进程

进程是一个正在运行的程序实例,拥有独立的地址空间、文件描述符、信号处理等资源。

进程状态

          创建
           ↓
就绪(Ready)←──── 运行(Running)
    ↑                    │
    │   时间片到/抢占      │ 等待 IO 或资源
    └──────────────  阻塞(Blocked)
                         ↑
                    IO 完成/资源就绪

运行 ──exit──→ 终止(Terminated)

PCB(进程控制块)

OS 用 PCB 描述和管理进程,包含:进程标识(PID)、CPU 寄存器状态、内存管理信息(页表基址)、IO 状态(打开的文件描述符)、调度信息(优先级、时间片)。


线程

线程是进程内的执行流,共享进程的地址空间和资源,但拥有独立的程序计数器(PC)、寄存器组和栈。

进程 vs 线程

进程线程
资源独立地址空间共享进程资源
创建开销大(fork 复制地址空间)
通信IPC(管道、共享内存等)直接读写共享变量
崩溃影响不影响其他进程会导致整个进程崩溃
切换开销大(需切换地址空间)

线程模型

模型说明示例
用户态线程由用户库管理,内核不感知,切换快协程、早期 goroutine
内核态线程由 OS 调度,可利用多核Linux pthread
混合模型(M:N)M 个用户线程映射到 N 个内核线程Go 运行时、Java 虚拟线程

上下文切换

CPU 从执行 A 切换到 B 的过程:

1. 保存 A 的寄存器、PC 等到 PCB/TCB
2. 调度器选择下一个运行的进程/线程
3. 从 B 的 PCB/TCB 恢复寄存器状态
4. 跳转到 B 的 PC 继续执行

进程切换还需刷新 TLB(切换地址空间),开销比线程切换更大。


进程间通信(IPC)

方式特点适用场景
管道(Pipe)单向,父子进程间,内核缓冲Shell 管道 |
命名管道(FIFO)双向,无关进程间本地进程通信
信号(Signal)异步通知,无数据进程控制(SIGKILL、SIGTERM)
共享内存最快,需同步机制高性能本地通信
消息队列有格式的消息传递解耦生产/消费
信号量(Semaphore)计数器,用于同步和互斥资源访问控制
Socket跨网络通信分布式系统

线程同步

多线程共享数据时需防止竞态条件(Race Condition):

机制说明
互斥锁(Mutex)同一时刻只有一个线程进入临界区
读写锁(RWLock)允许多读者并发,写者独占
信号量(Semaphore)控制对 N 个资源的并发访问
条件变量(Cond)配合互斥锁,条件不满足时阻塞,满足时唤醒
原子操作(Atomic)硬件级别的不可分割操作,无需加锁

协程(Coroutine)

协程是用户态的轻量级”线程”,由程序自主调度(非抢占),切换开销极小:

线程协程
调度者操作系统运行时/用户程序
切换开销较大(内核态)极小(用户态)
并行可真正并行单线程内并发
适用CPU 密集IO 密集

相关链接