我正在学习围棋,我在操场上做实验。我有一个非常简单的围棋代码。我试图在围棋例程中同时使用结构和切片。我不确定这是否会是我在生产中使用的东西,但它似乎有点偏离,所以在这里:
func main() {
routinemsg := make(chan []Person)
routinemsg2 := make(chan []Person)
// create the person records
p1 := newPerson("john doe", 25)
p2 := newPerson("dohn joe", 52)
p3 := newPerson("bohn joo", 30)
// send a slice of Person to the first routine
go func() { routinemsg <- []Person{p1, p2} }()
// retrieve the slice from the first routine[in the append]
// append p3 to the slice retrieved from the first routine
// send the new slice to the second routine
go func() { routinemsg2 <- append(<-routinemsg, p3) }()
// I am able to see the first Println but when I insert the second one I get a deadlock error
// also, same error if I use one Println with 2 arguments.
fmt.Println(<-routinemsg)
fmt.Println(<-routinemsg2)
}
我听说过等待小组,但还不知道他们!所以,对我好点:D和谢谢你的时间
2条答案
按热度按时间laximzn51#
routinemsg
上只有一个发送操作,但您有2个接收操作:一个在已启动的goroutine中,另一个在main
goroutine中,一个发送的值只能被一个接收者接收一次。如果启动的goroutine首先从
routinemsg
接收到消息,那么它将是一个死锁:main
中的接收将永远阻塞。如果
main
goroutine首先接收,那么被启动的goroutine将永远阻塞(试图从main
接收),因此它永远不能在routinemsg2
上发送任何东西,因此main
中从routinemsg2
接收的东西也将永远阻塞:再次陷入僵局。删除
main()
中的fmt.Println(<-routinemsg)
行,然后从routinemsg2
的最终接收可以(最终)继续,并将打印包含p1
、p2
和p3
的切片:在Go Playground上试用。
yqkkidmi2#
作为对@icza回答的补充:如果您使用如下所示的 * 缓冲通道 *,
您可以从同一通道多次发送和接收值。
但是,您仍然通过传递给make的参数来限制发送和接收的次数!此外,对于缓冲通道,您将总是按照发送到通道的顺序接收值。
因此,从第二个接收器接收的第二个值将始终是发送到通道的第二个值。