步骤 9 / 9
锁之外的工具
不同场景有更合适的同步方式:条件变量、读写锁、原子变量。
一个线程要等“队列不空”这样的条件时,用条件变量:没条件就睡,有人改了条件再叫醒它,不用反复检查。 读多写少的数据用读写锁,多个读者可以同时进。 只是一个计数器时,直接用原子操作(如 atomic_fetch_add)就够了,不必加锁。
操作系统
多个线程同时改同一份数据会出错,锁保证同一时刻只有一个线程在改。
以 Linux 上两个线程同时给计数器加 1、用 pthread_mutex 保护为例。
步骤 9 / 9
不同场景有更合适的同步方式:条件变量、读写锁、原子变量。
一个线程要等“队列不空”这样的条件时,用条件变量:没条件就睡,有人改了条件再叫醒它,不用反复检查。 读多写少的数据用读写锁,多个读者可以同时进。 只是一个计数器时,直接用原子操作(如 atomic_fetch_add)就够了,不必加锁。
| 当前状态 | 发生了什么 |
|---|---|
| 两个线程同时运行 | 两个线程读到同一个旧值,更新丢失 |
| 交错执行 | 执行顺序不可预测 |
| 动手实验 | 两个读都在写之前,丢一次更新 |
| 线程 1 持有锁 | 线程 1 独占临界区 |
| 线程 1 持有锁 | 线程 2 拿锁失败 |
| 线程 2 睡眠 → 被唤醒 | 线程 2 拿到锁,两次加 1 都生效 |
| 死锁 | 两个线程都在等 |
| 动手实验 | 等待图出现环即死锁 |
| 同步 | 选择合适的工具 |