2 回答
TA贡献1801条经验 获得超16个赞
通道可以是有缓冲的或无缓冲的。一个缓冲通道可以在它的“内部”存储许多项目,但是当你向缓冲通道添加一些东西时,添加项目的 goroutine 只能在另一个 goroutine 删除项目时继续。没有地方可以“离开”这个项目,它必须直接传递给另一个 goroutine,第一个 goroutine 会等到另一个 goroutine 从它那里拿走这个项目。
这就是您的代码中发生的事情。当您使用 来创建频道时make
,如果您没有将容量指定为第二个参数,您将获得一个无缓冲频道。要创建缓冲通道,请将第二个参数传递给make
,例如。
messages := make(chan string, 1) // could be larger than 1 if you want
这允许 goroutine 将项目(string
在本例中为a )添加到通道中,当另一个 goroutine 将来尝试从通道中获取项目时,该项目将可用,然后原始 goroutine 可以继续处理。
TA贡献1719条经验 获得超6个赞
我现在已经了解了很多关于频道的知识,现在我可以回答这个问题了。
在第 16 行,当主线程(goroutine)将消息“test”发送到通道时,执行会暂停,运行时会寻找其他准备好从通道消息接收值的 goroutine。由于没有其他通道,运行时会引发带有死锁消息的恐慌。这是死锁的典型例子。
要解决这个问题,可以做两件事。
1)按照马特的建议使用缓冲通道(答案之一)。
2) 否则在 goroutine 中有发送到 channel 或从 channel 接收的语句。
func main() {
messages := make(chan string)
go func() {
messages <- "test" //line 16
}()
fmt.Println(<-messages)
}
所以最重要的一点是,
1) 通道只能用于 goroutines 之间的通信,即当你发送到一个 goroutine 中的通道时,你只能在另一个不同的 goroutine 中接收它。
2) 当数据发送到 goroutine 中的通道时,该 goroutine 的流程/执行将暂停,直到从另一个 goroutine 中的同一通道接收到数据。
- 2 回答
- 0 关注
- 158 浏览
添加回答
举报