Skip to content
On this page

并发

Goroutine

go f() 启动 goroutine,由运行时调度到 OS 线程上(M:N 模型)。创建成本远低于线程,但仍非免费;海量 goroutine 应注意栈与调度开销。

Channel

chan T:未缓冲同步握手;带容量为缓冲通道。

go
ch := make(chan int, 2)
ch <- 1
v := <-ch
close(ch)
  • 已关闭 通道发送 → panic。
  • 从已关闭通道读:立即得到零值,okfalsev, ok := <-ch)。
  • 仅发送方应 close;重复 close panic。
  • nil 通道上收发永久阻塞,可用于 select 禁用某分支。

select

见控制流章。典型模式:超时

go
select {
case res := <-work:
    use(res)
case <-time.After(time.Second):
    return errors.New("timeout")
}

取消传播常用 context.ContextDone() 通道。

同步原语(sync

类型用途
Mutex / RWMutex互斥 / 读写锁
WaitGroup等待一组 goroutine 结束
Once保证某函数只执行一次
Cond条件变量
Pool对象池,减轻 GC;Get 返回值生命周期勿越界误用

sync/atomic 提供原子操作;复杂场景优先高层抽象或 channel;需要细粒度无锁时用 atomic 并注意内存序(Go 内存模型与原子文档)。

context

  • context.Background():根上下文。
  • WithCancel / WithTimeout / WithDeadline:派生可取消上下文,须调用返回的 cancel()(通常 defer cancel())避免泄漏 timer/goroutine。
  • WithValue:传递请求范围元数据,塞业务大对象或可选参数替代品。

常见陷阱

  1. 在 goroutine 中捕获循环变量:Go 1.22 前易错;现版本每轮独立,仍建议显式传参。
  2. 泄漏 goroutine:无退出条件的 for + 阻塞发送/接收。
  3. 死锁:锁顺序不一致、channel 无配对等。
  4. -race 检测数据竞争:未同步的并发读写同一内存位置。

并行度

GOMAXPROCS 控制可同时执行用户级 Go 代码的最大 OS 线程数;默认约等于 CPU 核数。CPU 密集任务勿盲目增大 goroutine 数。

技术文库