同步的目标是让并发访问满足不变量。互斥量保证同一时刻只有一个执行者进入临界区,适合保护共享结构;信号量维护许可计数,可限制并发资源数量,也可表达事件,但所有权语义通常弱于互斥量。

条件变量用于等待某个共享状态成立。正确模式是在持有互斥锁时用 while 检查谓词,不满足则等待;等待操作原子地释放锁并睡眠,唤醒后重新加锁、再次检查。使用 if 会受虚假唤醒或其他线程抢先消费影响。

自旋锁在等待时持续检查,不发生睡眠切换,适合临界区极短且预期等待很少的场景;持锁者被抢占或临界区含 I/O 时,自旋会浪费 CPU。futex 的思路是无竞争时在用户态用原子操作完成,发生竞争时才进入内核睡眠与唤醒,许多用户态锁基于此构建。

读写锁允许多个读者并行、写者独占,只有读多写少且临界区足够大时才可能获益,还需关注读者或写者饥饿。任何锁都要控制粒度:过大降低并行,过细增加复杂度和死锁风险。

误区是认为原子变量能自动保护多步不变量、条件变量本身保存事件、用自旋锁等待长任务、持锁调用未知回调,以及漏用 finally 释放。小结:先写共享谓词和所有权,再选择等待策略;锁是维护不变量的手段,不是越多越安全。