进程与线程
2026/1/15大约 3 分钟
进程与线程
进程
进程概念
进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位。
进程状态
┌─────────────────────────────────────────────────────────┐
│ 进程状态转换 │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌────────┐ │
│ 创建 ────> │ 就绪 │ <──── 时间片用完 │
│ └────┬───┘ │
│ │ │
│ 调度 │ │
│ ▼ │
│ ┌────────┐ ┌────────┐ │
│ │ 阻塞 │ <─── │ 运行 │ ────> 终止 │
│ └────┬───┘ └────────┘ │
│ │ ▲ │
│ │ │ │
│ └───────────────┘ │
│ I/O 完成 │
│ │
└─────────────────────────────────────────────────────────┘- 创建:进程正在被创建
- 就绪:等待 CPU 调度
- 运行:正在 CPU 上执行
- 阻塞:等待某事件(I/O)
- 终止:进程执行完毕
进程控制块(PCB)
┌─────────────────────────────────────────────────────────┐
│ PCB │
├─────────────────────────────────────────────────────────┤
│ 进程标识符(PID) │
│ 进程状态 │
│ 程序计数器(PC) │
│ CPU 寄存器 │
│ CPU 调度信息(优先级、调度队列指针) │
│ 内存管理信息(页表、段表) │
│ I/O 状态信息 │
│ 记账信息(CPU 时间、时间限制) │
└─────────────────────────────────────────────────────────┘进程调度算法
| 算法 | 说明 | 特点 |
|---|---|---|
| FCFS | 先来先服务 | 简单,对短作业不利 |
| SJF | 短作业优先 | 平均等待时间最短 |
| 优先级 | 按优先级调度 | 可能饥饿 |
| 时间片轮转 | 固定时间片 | 公平,响应快 |
| 多级反馈队列 | 多个队列,不同优先级 | 综合性能好 |
线程
线程概念
线程是 CPU 调度的基本单位,是进程中的执行流。
进程 vs 线程
| 特性 | 进程 | 线程 |
|---|---|---|
| 资源 | 独立地址空间 | 共享进程资源 |
| 开销 | 创建/切换开销大 | 开销小 |
| 通信 | IPC(管道、消息队列) | 共享内存 |
| 影响 | 一个崩溃不影响其他 | 一个崩溃影响整个进程 |
线程模型
┌─────────────────────────────────────────────────────────┐
│ 线程模型 │
├─────────────────────────────────────────────────────────┤
│ │
│ 1:1 模型(一对一) │
│ ┌─────────┐ ┌─────────┐ │
│ │用户线程1│────│内核线程1│ │
│ └─────────┘ └─────────┘ │
│ ┌─────────┐ ┌─────────┐ │
│ │用户线程2│────│内核线程2│ │
│ └─────────┘ └─────────┘ │
│ │
│ N:1 模型(多对一) │
│ ┌─────────┐ │
│ │用户线程1│──┐ │
│ └─────────┘ │ ┌─────────┐ │
│ ┌─────────┐ ├──│内核线程 │ │
│ │用户线程2│──┘ └─────────┘ │
│ └─────────┘ │
│ │
│ M:N 模型(多对多) │
│ ┌─────────┐ ┌─────────┐ │
│ │用户线程1│──┬─│内核线程1│ │
│ └─────────┘ │ └─────────┘ │
│ ┌─────────┐ │ ┌─────────┐ │
│ │用户线程2│──┴─│内核线程2│ │
│ └─────────┘ └─────────┘ │
│ │
└─────────────────────────────────────────────────────────┘进程间通信(IPC)
通信方式
| 方式 | 说明 | 特点 |
|---|---|---|
| 管道 | 半双工,父子进程 | 简单,容量有限 |
| 命名管道 | 无亲缘关系进程 | 文件系统中可见 |
| 消息队列 | 消息链表 | 可随机读取 |
| 共享内存 | 映射同一物理内存 | 最快,需同步 |
| 信号量 | 计数器 | 用于同步 |
| 信号 | 异步通知 | 简单,信息量少 |
| Socket | 网络通信 | 可跨主机 |
共享内存
// 创建共享内存
int shmid = shmget(key, size, IPC_CREAT | 0666);
// 映射到进程地址空间
void *ptr = shmat(shmid, NULL, 0);
// 使用共享内存
strcpy(ptr, "Hello");
// 解除映射
shmdt(ptr);
// 删除共享内存
shmctl(shmid, IPC_RMID, NULL);同步与互斥
临界区
┌─────────────────────────────────────────────────────────┐
│ 临界区问题 │
├─────────────────────────────────────────────────────────┤
│ │
│ 进入区(Entry Section) │
│ ↓ │
│ 临界区(Critical Section) ← 访问共享资源 │
│ ↓ │
│ 退出区(Exit Section) │
│ ↓ │
│ 剩余区(Remainder Section) │
│ │
└─────────────────────────────────────────────────────────┘信号量
// P 操作(等待)
void P(semaphore *s) {
s->value--;
if (s->value < 0) {
// 阻塞当前进程
block(s->queue);
}
}
// V 操作(释放)
void V(semaphore *s) {
s->value++;
if (s->value <= 0) {
// 唤醒一个等待进程
wakeup(s->queue);
}
}死锁
必要条件:
- 互斥条件
- 占有并等待
- 不可抢占
- 循环等待
预防死锁:
- 破坏互斥:使用可共享资源
- 破坏占有等待:一次申请所有资源
- 破坏不可抢占:可抢占资源
- 破坏循环等待:资源有序分配
避免死锁:
- 银行家算法