无缓冲通道是否等待数据?
does unbuffered channel wait for data?
我有这个程序:
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
中调用f1
/f2
,就会报dead lock
错误。
我不明白 f1/f2 对 ch1/ch2 做了什么。
你能帮忙解释一下他们的行为吗?
f1()
和f2()
都有接收操作。这些是阻塞操作:只要通道上没有人发送任何东西,它们就会等待。
所以你启动 f1()
和 f2()
作为新的 goroutines,然后 main()
休眠。同时 f1()
和 f2()
正在等待来自 ch1
和 ch2
的数据。
然后 main()
醒来,并尝试在 ch1
上发送一个值。这没问题,因为有一个 goroutine 准备好从它接收 (f1()
)。然后 main()
尝试在 ch2
上发送,这也可以,f2()
已准备好接收。
然后main()
returns,app结束(不等待其他goroutines打印)。
如果你不启动 f1()
和 f2()
作为新的 goroutines,当 main()
到达发送语句时,将没有人准备好从通道接收,并且由于它是无缓冲的,它会阻塞。由于不会再有任何 goroutines 运行,这是一个死锁。
我有这个程序:
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
中调用f1
/f2
,就会报dead lock
错误。
我不明白 f1/f2 对 ch1/ch2 做了什么。
你能帮忙解释一下他们的行为吗?
f1()
和f2()
都有接收操作。这些是阻塞操作:只要通道上没有人发送任何东西,它们就会等待。
所以你启动 f1()
和 f2()
作为新的 goroutines,然后 main()
休眠。同时 f1()
和 f2()
正在等待来自 ch1
和 ch2
的数据。
然后 main()
醒来,并尝试在 ch1
上发送一个值。这没问题,因为有一个 goroutine 准备好从它接收 (f1()
)。然后 main()
尝试在 ch2
上发送,这也可以,f2()
已准备好接收。
然后main()
returns,app结束(不等待其他goroutines打印)。
如果你不启动 f1()
和 f2()
作为新的 goroutines,当 main()
到达发送语句时,将没有人准备好从通道接收,并且由于它是无缓冲的,它会阻塞。由于不会再有任何 goroutines 运行,这是一个死锁。