Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

同步原语

本章介绍 ASCO 提供的同步原语。它们用于在多个并发执行流之间建立互斥与协调关系。

本章只描述行为与语义:你能做什么、它会怎样表现、以及常见用法。


目录


选型建议

何时使用 channel

channel 适合在并发执行流之间传递值,并通过等待来表达背压(缓冲满时发送等待,缓冲空时接收等待)。

何时使用 spinlock

spinlock 适合保护非常短的临界区:

  • 修改一个小的共享状态(例如计数器、指针、短容器操作);
  • 临界区内不进行可能长时间运行的操作。

注意:

  • 不要在持有锁期间跨越 co_await

何时使用 semaphore

semaphore 适合表达“许可”的语义:

  • 并发限流(最多允许同时进行 N 个工作);
  • 生产者/消费者式的资源计数(有资源才能继续)。

acquire() 是可等待操作:当许可不足时会等待直到有许可被释放。

何时使用 rwlock

rwlock 适合保护“读多写少”的共享状态:

  • 多个 reader 同时读取是安全且有价值的;
  • 写入虽然较少,但写入时需要与所有 reader 互斥;
  • 你希望一旦 writer 开始等待,后续 reader 不再继续插队。

如果读写比例并不偏向读取,或者临界区极短,通常 mutex 会更直接。

何时使用 condition_variable

condition_variable 适合表达“等某个条件成立,然后由别的任务通知我继续”:

  • 条件本身保存在外部共享状态里;
  • 等待方通过 predicate 判断是否可以继续;
  • 状态改变后,由生产者调用 notify_one() / notify(n) 唤醒等待方;必要时也可以使用带 predicate 的通知重载做额外门控。

它本身不拥有被保护的数据,也不提供互斥;若 predicate 访问共享状态,调用方需要自行保证可见性与并发安全。


常见约定

  • try_* 系列 API 表达“不等待的快速路径”;失败时走其它分支。
  • 需要等待时,优先用明确的同步原语(例如 semaphore::acquire()),避免忙等。