# Closing 2 channels in one Go routine causes deadlock?

Hi, I am playing with Tour of Go exercise Equivalent Binary Trees. I have completed the code but I notice something strange:

``````package main

import "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) {
if t == nil {
return
}
Walk(t.Left, ch)
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 := make(chan int)
c2 := make(chan int)

go func() {
Walk(t1, c1)
close(c1)
}()
go func() {
Walk(t2, c2)
close(c2)
}()

for i := range c1 {
if i != <-c2 {
return false
}
}

return true
}

func main() {
println(Same(tree.New(10), tree.New(10)))
}
``````

As can be seen, in the Same method, if I use the following equivalent code instead, then deadlock will arise. Can someone help me explain this problem? Thanks

``````	go func() {
Walk(t1, c1)
close(c1)
Walk(t2, c2)
close(c2)
}()``````
2. It enters `Walk(t1, c1)`
3. `Walk(t1, c1)` sends its first value into `c1`
4. Your main goroutine receives the first value from `c1` in the for ā¦ range loop
5. Your main goroutine attempts a receive from `c2` to compare it to the value from `c1`.
6. Your āwalker goroutineā hasnāt returned from `Walk(t1, c1)` yet, so `Walk(t2, c2)` hasnāt started. Nothing is getting sent into `c2`, so receiving from it will deadlock.
1 Like

main and go1 all blocked.
main need recv ch1 and ch2, but not recv ch2. go1 not send value to c2 in block state, so main revc c2 in block state,all goroutine to blocked state.

• go1 send c1-10 succes
• main c1 recv c1-10 succes
• main wait c2 recv
• go1 send c2-20 block

https://play.golang.org/p/Ji-ysAFdISI

g1 need c1 send 10ci value 10-100, then c2 send 10ci.
main need recv c1 then recv c2 Repeat 10ci.
but g1 send ā20ā main is blocked state wait revc c2,so g1 and main in blocked, if c1 and c2 cap is 10,then not blocked.

Thanks. I somehow get it. But I have one more question: Why āsend 20ā must wait for range to pop it out? I mean, from my point of view, it is in a different thread, so why canāt we just put to channel independently?

Feels like there is a mutex or something c1.

Thanks

Thank you, I somehow get it.

it is in a different goroutine, Chan is essentially a blocking queue with a lock.
chan accepts a value that is blocked if there is no data, and sends a value that is also blocked if chan is full.