【发布时间】:2020-04-09 23:14:48
【问题描述】:
我有这个程序:
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")
}
我希望,只要 f1 和 f2 不打印任何东西,就意味着 ch1 和 ch2 里面什么都没有,所以 ch1<-1 和 ch2<-2 应该阻塞?
但运行时,它会打印:
no buffered channel will wait?
main exits
为什么那些无缓冲的频道 ch1 和 ch2 在 main 中没有被阻塞?
如果我在main中不调用f1/f2,就会报dead lock错误。
我不明白 f1/f2 对 ch1/ch2 做了什么。
您能帮忙解释一下他们的行为吗?
【问题讨论】:
-
通常的约定是谈论
buffered或unbuffered频道。其中buffered频道有一个buffer length > 1,它允许push无需等待pop操作。另一方面,由于unbuffered通道有一个空缓冲区,每个push操作都需要来自另一个例程的pop。