让相互隔离的进程能安全协作,同时不把共享状态写乱。
| 协作需求 | 直接做会怎样坏 | 被迫设计 |
|---|---|---|
| 一个进程把字节流交给另一个进程 | 直接共享缓冲区会越界、覆盖、丢数据 | pipe |
| 父进程等待子进程结束 | 忙等浪费 CPU,状态可能错过 | wait / wakeup |
| 多个进程共享一段状态 | 同时写导致状态撕裂 | 锁、信号量、条件变量 |
| 内核和驱动共享队列 | 中断和进程上下文并发修改队列 | 关中断区、spinlock、队列协议 |
| 对象 | 字段 | 负责什么 |
|---|---|---|
Pipe | buffer、read_pos、write_pos、closed_read、closed_write | 保存进程间字节流 |
PipeReader | pipe、offset、flags | 读端 fd 引用 |
PipeWriter | pipe、offset、flags | 写端 fd 引用 |
WaitQueue | waiting_processes、condition | 读空、写满时阻塞和唤醒 |
| 机制 | 解决什么 | 最小规则 |
|---|---|---|
| mutex | 同一时刻只有一个执行流修改共享状态 | 持锁时间短,退出路径必须释放 |
| semaphore | 有限数量资源的占用与释放 | 计数不能负,释放要唤醒等待者 |
| condition variable | 等待某个状态变成真 | 检查条件和 sleep 必须原子衔接 |
| wait queue | 把进程挂到等待条件上 | wakeup 要对应具体条件,不要乱唤醒 |
| 失败 | 原因 | 设计防线 |
|---|---|---|
| 丢唤醒 | 检查条件和睡眠不是原子过程 | 在锁保护下检查条件并进入 wait queue |
| 死锁 | 两个进程互相等待对方持有的锁 | 固定锁顺序,禁止持锁等待外部事件 |
| 饥饿 | 某个等待者长期拿不到资源 | 等待队列 FIFO 或公平策略 |
| 优先级反转 | 低优先级持锁阻塞高优先级 | 第一版先记录风险,第二版再做继承 |
| 实验 | 通过标准 | 证明了什么 |
|---|---|---|
| pipe 字节流 | A 写入,B 按顺序读出 | IPC 数据传递成立 |
| 读空阻塞 | pipe 空时 read 睡眠,write 后被唤醒 | wait / wakeup 成立 |
| 写满阻塞 | pipe 满时 write 睡眠,read 后恢复 | 背压成立 |
| 锁保护 | 多进程递增共享计数,结果不丢增量 | 互斥成立 |
| 关闭语义 | 写端关闭后,读端读完剩余数据返回 EOF | 引用与生命周期成立 |