<p>Hello, I am going through a tour of go, and cannot understand why I have a deadlock in my code. This is my (not working) solution to the binary trees exercise. </p>
<pre><code>package main
import (
"fmt"
"golang.org/x/tour/tree"
)
// Walk walks the tree t sending all values
// from the tree to the channel ch.
func Walk(t *tree.Tree, ch chan int) {
switch true {
case t.Left == nil && t.Right == nil:
ch <- t.Value
case t.Left != nil && t.Right != nil:
Walk(t.Left, ch)
ch <- t.Value
Walk(t.Right, ch)
case t.Left != nil:
Walk(t.Left, ch)
ch <- t.Value
case t.Right != nil:
ch <- t.Value
Walk(t.Right, ch)
}
}
// Same determines whether the trees
// t1 and t2 contain the same values.
func Same(t1, t2 *tree.Tree) bool {
c1, c2 := make(chan int), make(chan int)
go Walk(t1, c1)
go Walk(t2, c2)
same := true
for i := range(c1) {
if i != <-c2 {
same = false
break
}
}
return same
}
func main() {
t1, t2 := tree.New(1), tree.New(1)
t3, t4 := tree.New(1), tree.New(2)
fmt.Println(Same(t1, t2))
fmt.Println(Same(t3, t4))
}
</code></pre>
<p>What i don't understand is that I am calling my Walks from the Same function. Why are they all dead locked?</p>
<p>If I make all my recursive Walk functions goroutines that does not cause a deadlock but then my tree traversal will not be in order since the processing will all be on different threads so that isn't viable. But why does that scenario not cause a deadlock?</p>
<p>Baby Gopher calls for aid!</p>
<hr/>**评论:**<br/><br/>justinisrael: <pre><p>The deadlock is because you never close the channels. The range will keep blocking because it is waiting for more values (same with the single pull from the second channel). Once your trees have finished walking, the channel could be closed to indicate no more values. </p></pre>justinisrael: <pre><p>I should have been more specific where to add it. It would be best to wrap those top level Walk calls in an anonymous function that calls close on the chan after the Walk returns (in the goroutine) </p></pre>
