跳到主要内容

并发设计

数据竞争是什么, 如何处理?​

  • data race: 多个 goroutine 访问同一内存位置,至少一个写入,而且访问之间没有建立必要的同步顺序;

  • 风险: 结果不确定, 程序行为不可靠;

  • 处理方式: channel 传递数据, mutex 保护共享数据, 避免共享可变状态;

  • 检查手段: 使用 go test -race ./... 检测已执行路径中的数据竞争;没有报告只能说明本次运行未检测到,不能证明所有调度都安全;

CSP 模型是什么, Go 如何表达?​

  • CSP: Communicating Sequential Processes;

  • 核心思想: 并发实体通过通信协作, 而不是直接共享状态;

  • Go 表达: goroutine 表示并发执行单元, channel 表示通信通道;

  • 实践原则: 通过通信共享内存, 而不是通过共享内存通信;

  • 所有权转移: 把 slice 或指针放入 channel 后,发送方若继续修改相同底层数据,仍可能与接收方竞争;“通过通信”必须配合明确的共享或移交约定;

并发设计的基本原则有哪些?​

  • 所有权: 明确哪个 goroutine 负责修改某份数据;

  • 通信: 使用 channel 传递数据或事件;

  • 共享: 必须用锁或其他同步原语保护;

  • 退出: goroutine 应有明确结束条件;

  • 边界: 每个 goroutine 内部自行处理 panic 或将错误传回调用方;

  • 退出设计: 明确正常完成、调用方取消与失败三条出口,不能只描述 goroutine 的启动条件;

  • 数据所有者: 给共享数据指定唯一写入者,或为所有读写规定同一同步方式,避免一部分路径加锁而另一部分绕开;

  • 错误传递: 子 goroutine 的返回值不会自动交还启动者,应通过结果通道或任务结果结构传回;

在哪里根据协调目标选择具体同步机制?​