Goでgo routineがdeadlockする
下記のGoのコードでWalkerを実行するとgo routineがdeadlockされてしまいます。
deadlockされずに全てのNodeのValueを実行するにはどうすればいいのでしょうか?
そして、なぜdeadlockになってしまうのでしょうか?
参考: https://golang.org/doc/play/tree.go
package main
import (
"fmt"
"math"
"math/rand"
"time"
)
type Node struct {
Value int64
Left, Right, Parent *Node
}
func (n *Node) Insert(num int64) *Node {
if num > n.Value {
if n.Left == nil {
n.Left = &Node{Parent: n, Value: num}
return n
}
n.Left.Insert(num)
} else if num < n.Value {
if n.Right == nil {
n.Right = &Node{Parent: n, Value: num}
return n
}
n.Right.Insert(num)
}
return n
}
func (n *Node) Walk(x chan int64) {
if n == nil {
return
}
fmt.Println(n.Value)
n.Left.Walk(x)
x <- n.Value
n.Right.Walk(x)
}
func Walker(n *Node) chan int64 {
ch := make(chan int64)
go func() {
n.Walk(ch)
}()
return ch
}
func Randint(min, max int64) int64 {
f64_min := float64(min)
f64_max := float64(max)
r := rand.New(rand.NewSource(time.Now().UnixNano()))
return int64(math.Floor(r.Float64()*(f64_max-f64_min+1)) + f64_min)
}
func main() {
root := &Node{Value: 1264523}
for i := 0; i < 100; i++ {
y := Randint(0, 12345667)
root.Insert(y)
}
ch := Walker(root)
for {
value, ok := <-ch
if !ok {
break
}
fmt.Println(value)
}
}