为什么这段代码会产生错误?

下面的一段代码为什么会产生错误?


func main() {


    messages := make(chan string)


    messages <- "test" //line 16


    fmt.Println(<-messages)


}

生成以下错误。


fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:

main.main()

    /tmp/sandbox994400718/main.go:16 +0x80

一个值被发送到通道,并在下一行被接收。从技术上讲,它应该可以工作。


慕慕森
浏览 159回答 2
2回答

侃侃尔雅

通道可以是有缓冲的或无缓冲的。一个缓冲通道可以在它的“内部”存储许多项目,但是当你向缓冲通道添加一些东西时,添加项目的 goroutine 只能在另一个 goroutine 删除项目时继续。没有地方可以“离开”这个项目,它必须直接传递给另一个 goroutine,第一个 goroutine 会等到另一个 goroutine 从它那里拿走这个项目。这就是您的代码中发生的事情。当您使用 来创建频道时make,如果您没有将容量指定为第二个参数,您将获得一个无缓冲频道。要创建缓冲通道,请将第二个参数传递给make,例如。messages&nbsp;:=&nbsp;make(chan&nbsp;string,&nbsp;1)&nbsp;//&nbsp;could&nbsp;be&nbsp;larger&nbsp;than&nbsp;1&nbsp;if&nbsp;you&nbsp;want这允许 goroutine 将项目(string在本例中为a&nbsp;)添加到通道中,当另一个 goroutine 将来尝试从通道中获取项目时,该项目将可用,然后原始 goroutine 可以继续处理。

慕侠2389804

我现在已经了解了很多关于频道的知识,现在我可以回答这个问题了。在第 16 行,当主线程(goroutine)将消息“test”发送到通道时,执行会暂停,运行时会寻找其他准备好从通道消息接收值的 goroutine。由于没有其他通道,运行时会引发带有死锁消息的恐慌。这是死锁的典型例子。要解决这个问题,可以做两件事。1)按照马特的建议使用缓冲通道(答案之一)。2) 否则在 goroutine 中有发送到 channel 或从 channel 接收的语句。func main() {&nbsp; &nbsp; messages := make(chan string)&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; messages <- "test" //line 16&nbsp; &nbsp; }()&nbsp; &nbsp; fmt.Println(<-messages)}所以最重要的一点是,1) 通道只能用于 goroutines 之间的通信,即当你发送到一个 goroutine 中的通道时,你只能在另一个不同的 goroutine 中接收它。2) 当数据发送到 goroutine 中的通道时,该 goroutine 的流程/执行将暂停,直到从另一个 goroutine 中的同一通道接收到数据。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go