前置知识: Go

goroutine与channel通信原理

1 minAdvanced2026/6/14

Go goroutine与channel通信原理详解。

1. goroutine 原理

goroutine 是用户态线程,初始栈仅 2KB,可动态增长:

go func() {
    fmt.Println("Hello from goroutine")
}()

1.1 与线程对比

特性goroutineOS 线程
初始栈2KB1-8MB
创建成本~0.3μs~10μs
切换成本~0.2μs~1-2μs
数量上限百万级千级

2. channel 通信

// 无缓冲 channel:同步
ch := make(chan int)

// 有缓冲 channel:异步
ch := make(chan int, 100)

// 发送
ch <- 42

// 接收
value := <-ch

// 关闭
close(ch)

// 遍历
for v := range ch {
    fmt.Println(v)
}

3. 通信原理

3.1 无缓冲 channel

发送方阻塞直到接收方就绪,反之亦然。实现同步语义。

3.2 有缓冲 channel

缓冲区满时发送方阻塞,缓冲区空时接收方阻塞。

3.3 底层数据结构

type hchan struct {
    qcount   uint           // 缓冲区元素数
    dataqsiz uint           // 缓冲区大小
    buf      unsafe.Pointer // 环形缓冲区
    elemtype *_type         // 元素类型
    sendx    uint           // 发送索引
    recvx    uint           // 接收索引
    recvq    waitq          // 等待接收的 goroutine 队列
    sendq    waitq          // 等待发送的 goroutine 队列
    lock     mutex          // 互斥锁
}

4. select 多路复用

select {
case v := <-ch1:
    fmt.Println("ch1:", v)
case v := <-ch2:
    fmt.Println("ch2:", v)
case <-time.After(5 * time.Second):
    fmt.Println("timeout")
default:
    fmt.Println("no data")
}