请帮我理解为什么入站<-done
在这种情况下没有接收到 channel ?
func main() {
done := make(chan bool)
println("enter")
defer func() {
println("exit")
}()
defer func() {
println(" notify start")
done <- true
println(" notify end")
}()
go func() {
println(" wait start")
<-done
println(" wait end")
}()
time.Sleep(time.Millisecond) // << when this is removed, it works.
}
我期望输出是:
enter
notify start
wait start
wait end
notify end
exit
但它是:
enter
wait start
notify start
notify end
exit
我最初假设 done
channel 以某种方式被提前关闭或清理,但即使在 done
时也会导致同样的意外行为。是全局性的。
不应该<-done
阻止直到 done <- true
发生?反之亦然?
决议
我似乎希望程序在退出之前等待所有 goroutines 完成。这是一个错误的假设。
这是一个肮脏的解决方法:
func main() {
done, reallydone := make(chan bool), make(chan bool)
println("enter")
defer func() {
<-reallydone
println("exit")
}()
go func() {
println(" wait start")
<-done
println(" wait end")
reallydone <- true
}()
defer func() {
println(" notify start")
done <- true
println(" notify end")
}()
time.Sleep(time.Millisecond)
}
最佳答案
当您使用 sleep 时,它会为 goroutine 提供启动时间,然后在它从 channel 读取时,main 在最后一个 println("wait end")
被调用之前退出。
但是,如果您不调用 sleep,defer 将阻塞,直到 goroutine 从中读取并为其提供足够的时间来打印。
如果您将代码移动到不同的函数并从 main 调用它,它将按预期工作。
func stuff() {
done := make(chan bool)
println("enter")
defer func() {
println("exit")
}()
go func() {
println(" wait start")
<-done
println(" wait end")
}()
defer func() {
println(" notify start")
done <- true
println(" notify end")
}()
}
func main() {
stuff()
}
关于Golang 入站 channel 未在 goroutine 中接收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25341047/