Go 无缓冲通道是否等待数据?
我有这个计划:Go 无缓冲通道是否等待数据?,go,locking,buffer,channel,Go,Locking,Buffer,Channel,我有这个计划: package main import ( "fmt" "time" ) var ch1 = make(chan int) var ch2 = make(chan int) func f1() { select { case <-ch1: fmt.Println("ch1") } } func f2() { select { case <-ch2: fmt.Println("
package main
import (
"fmt"
"time"
)
var ch1 = make(chan int)
var ch2 = make(chan int)
func f1() {
select {
case <-ch1:
fmt.Println("ch1")
}
}
func f2() {
select {
case <-ch2:
fmt.Println("ch2")
}
}
func main() {
go f1()
go f2()
time.Sleep(2 * time.Second)
fmt.Println("no buffered channel will wait?")
ch1 <- 1
ch2 <- 2
fmt.Println("main exits")
}
为什么那些无缓冲通道ch1
和ch2
没有在main中被阻塞
如果我没有在main
中调用f1
/f2
,它将报告死锁
错误
我不明白f1/f2对ch1/ch2做了什么
请您解释一下他们的行为好吗?这两个f1()
和f2()
都有接收操作。这些都是阻塞操作:只要没有人在通道上发送任何东西,他们就会等待
因此,您可以启动f1()
和f2()
作为新的goroutines,然后main()
休眠。同时f1()
和f2()
正在等待来自ch1
和ch2
的数据
然后main()
唤醒,并尝试在ch1
上发送一个值。这是正常的,因为有一个goroutine准备从它接收(f1()
)。然后main()
尝试发送ch2
,这也没问题,有f2()
准备接收
然后main()
返回,应用程序结束(它不等待其他goroutine打印)
如果您没有将
f1()
和f2()
作为新的goroutines启动,当main()
到达send语句时,将没有人准备好接收来自通道的消息,因为它是无缓冲的,它将被阻塞。由于不再有goroutines运行,这是一个死锁。通常的惯例是谈论缓冲的
或无缓冲的
通道。其中缓冲
通道具有缓冲长度>1
,允许推送
,而无需等待弹出
操作。另一方面,由于无缓冲
通道的缓冲区为空,因此每次推送
操作都需要另一个例程的弹出
。
no buffered channel will wait?
main exits