You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Go语言无缓冲通道(Unbuffered channel)阻塞机制的技术问询

你的理解完全正确!

无缓冲通道的核心逻辑就是这么回事——发送操作会一直阻塞发起它的goroutine,直到有其他goroutine对同一个通道执行接收操作,反过来接收操作也会阻塞,直到有对应的数据发送过来。

咱们拿你给的代码实例拆解下就清楚了:

package main

import "fmt"

func main() {
    ch01 := make(chan string)
    go func() {
        fmt.Println("We are in the sub goroutine")
        fmt.Println(<-ch01)
    }()
    fmt.Println("We are in the main goroutine")
    ch01 <- "Hello"
}

对应的运行结果:

We are in the main goroutine
We are in the sub goroutine
Hello

具体的执行顺序是:

  • 主goroutine先创建无缓冲通道ch01,接着启动子goroutine。
  • 主goroutine继续往下走,先打印We are in the main goroutine,然后执行ch01 <- "Hello"——这一步主goroutine就卡住了,也就是你说的阻塞,因为此时还没有goroutine在接收这个通道的数据。
  • 子goroutine开始运行,先打印We are in the sub goroutine,然后执行<-ch01准备接收数据。这时候发送和接收操作对上了,数据"Hello"从主goroutine传到子goroutine,主goroutine的阻塞状态解除(之后主goroutine就执行完退出了),子goroutine接着打印出收到的"Hello",然后也退出。

这种阻塞同步的特性,正是无缓冲通道用来协调多个goroutine执行顺序的关键,能保证数据传递的时机完全匹配双方的准备状态。

内容的提问来源于stack exchange,提问作者Pauli

火山引擎 最新活动