跳到主要内容

并发与性能

并发是为了重叠等待(I/O、锁、计时器),不是为了「更多线程 = 更快」。本篇归纳模型选择、常见故障模式,以及可重复的测量步骤。

并发模型对照

模型机制适合注意
多线程 + 共享内存OS 线程、锁、条件变量CPU 并行、细粒度共享状态死锁、伪共享、优先级反转
协程 / async-await协作式调度、事件循环高并发 I/O(HTTP、DB)阻塞调用会卡住整个 loop
Actor / 消息邮箱、无共享可变状态分布式、状态机背压、消息顺序、超时
数据并行分片、map-reduce、GPU批处理、矩阵拆分成本、内存带宽

Swiftasync/await + Task + actor;UI 相关状态用 @MainActor
TypeScript/Node:单线程 event loop;CPU 密集用 worker 线程或下沉到原生。
Go:goroutine + channel;注意泄漏与无缓冲 channel 死锁。

正确性:三件事

  1. 互斥:同一可变状态同时只有一个写者(或读者-写者规则明确)。
  2. 可见性:一个线程的写入对另一个线程可见(内存模型、 @MainActor、volatile 的误用)。
  3. 有序:happens-before 关系成立(锁、channel 发送、atomic)。
注意

数据竞争:未同步的并发读写是未定义行为(Rust/Swift 编译期尽量拒绝;C/C++ 仍可能发生)。优先用类型系统与 actor 隔离,而不是「多加一把锁」。

性能排查流程

步骤动作工具示例
1. 定义指标p95 延迟、吞吐、错误率、内存峰值SLI/SLO、产品埋点
2. 复现负载接近生产的 QPS、payload、冷/热缓存k6, wrk, 自定义脚本
3. Profile找热点函数与等待Instruments, perf, py-spy
4. 分类CPU / 分配 / 锁 / I/O / 外部依赖火焰图 + 追踪 span
5. 改动一次只改一类假设前后对比 + 回归测试

快路径原则:先减等待(批处理、连接池、缓存、异步 I/O),再减计算(算法、SIMD、原生扩展)。

反模式清单

反模式症状改法
线程池过大上下文切换飙升按 CPU 核数与阻塞比例调参
全局可变单例偶发崩溃、脏读注入依赖、actor、不可变快照
async 里阻塞延迟尖刺await 专用 API、线程池 offload
无界队列内存暴涨、延迟雪崩背压、限流、丢弃策略文档化
过早并行化复杂度↑收益≈0Amdahl:先 profile 串行瓶颈

与架构的衔接

  • 跨模块异步边界要有超时、取消、幂等约定,见 边界与契约
  • 发布与回滚节奏影响「能否承受并发 bug」,见 CI/CD

相关篇章