我不太明白binarytrees_quit.go中退出通道变量的目的。或者,我在这里错过了重点。我可以理解接收器可以发送值退出以告诉go例程返回或退出。但我认为这不是这种情况。是否只是为了确保Walk例程一直保持到相同完成执行?不会因为频道没有缓冲而不再常规。即使是这种情况,这也没有任何意义。请帮我理解。
提前致谢!
答案 0 :(得分:2)
您可以在“Go for gophers - GopherCon closing keynote - 25 April 2014 - Andrew Gerrand ”
中看到详细内容提早停止 向助行器添加
quit
频道,以便我们可以在中途停止。
func walk(t *tree.Tree, ch chan int, quit chan struct{}) {
if t.Left != nil {
walk(t.Left, ch, quit)
}
select {
case ch <- t.Value:
// vvvvvvvvvvvv
case <-quit:
return
}
// ^^^^^^^^^^^^
if t.Right != nil {
walk(t.Right, ch, quit)
}
}
创建退出频道并将其传递给每个助行器 在
quit
退出时关闭Same
,任何正在运行的步行者都会被终止。
func Same(t1, t2 *tree.Tree) bool {
// vvvvvvvvvvvv
quit := make(chan struct{})
defer close(quit)
w1, w2 := Walk(t1, quit), Walk(t2, quit)
// ^^^^^^^^^^^^
for {
v1, ok1 := <-w1
v2, ok2 := <-w2
if v1 != v2 || ok1 != ok2 {
return false
}
if !ok1 {
return true
}
}
}
安德鲁补充说:
为什么不杀死goroutines?
Goout代码看不到Goroutines。他们不能被杀或等待 你必须自己建立。
有一个原因:
只要Go代码知道它运行在哪个线程中,就会获得线程局部性 线程局部性破坏了并发模型。
- 频道只是价值观;它们适合类型系统。
- Goout代码看不到Goroutines;这为你提供了并发性。
少即是多。