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




