【发布时间】:2021-08-24 04:21:42
【问题描述】:
我是一个 golang 初学者,在学习 channel 和 goroutine 时遇到了一些麻烦。我的一个难点是 golang 通道阻塞机制是如何工作的。在golang tour,上面写着By default, sends and receives block until the other side is ready.,我根据自己的理解做了一些实验,得到了结果,fatal error: all goroutines are asleep - deadlock!。这个提示并没有真正让我了解错误是如何发生的。我google了一下,几乎每一篇文章都是关于channel的深层机制,或者假设读者理解了block这个词已经给出了所有的信息。
但作为初学者我有很多疑问,比如:
- 同一个 go-routine 写入通道后是否可以执行通道读取操作?
- 如果一个通道被阻塞,其他 go-routine 是否仍然可以向它发送消息?
- 如果 go-routine 尝试向被阻塞的频道发送消息,会发生什么?它会通过一个错误,或者什么都没发生,还是?
下面是我的一个让我困惑的测试?(据我所知,main func 是一个 go-routine,我认为它在执行过程中是同一个)
package main
import "time"
func chanWrite(s string, ch chan string) {
ch <- s
println("write", s)
}
func chanRead(ch chan string) {
println("read", <- ch)
}
// main func 1
func main() {
ch := make(chan string)
go chanWrite("A", ch)
time.Sleep(time.Second)
}
// main func 1 didn't throw error
// main func 2(modify main func 1 and then execute it)
func main() {
ch := make(chan string)
chanWrite("A", ch)
time.Sleep(time.Second)
}
// main func 2 throw error: "fatal error: all goroutines are asleep - deadlock!"
我在这个测试中看到的是在某种情况下,当我在没有读取的情况下将内容写入通道时,我得到了fatal error,有时什么也没有发生(比如在 main func 1 中)。
那么,有人能以一种简单而有趣的方式解释通道块是如何工作的,以便 golang 初学者可以轻松理解它吗?
【问题讨论】: