Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 通道死锁_Go_Deadlock_Goroutine - Fatal编程技术网

Go 通道死锁

Go 通道死锁,go,deadlock,goroutine,Go,Deadlock,Goroutine,我正在Go-with通道中构建一个异步Btree,但是我得到了错误致命错误:所有Goroutine都处于休眠状态-死锁我不知道为什么,因为我从带有缓冲通道的for循环中的通道获取值 type Obj interface { Compare(node Obj) int } type Tree struct { Item Obj Rigth, Left *Tree height int16 } func NewTree() *Tree {

我正在Go-with通道中构建一个异步Btree,但是我得到了错误
致命错误:所有Goroutine都处于休眠状态-死锁我不知道为什么,因为我从带有缓冲通道的for循环中的通道获取值

type Obj interface {
    Compare(node Obj) int
}

type Tree struct {
    Item        Obj
    Rigth, Left *Tree
    height      int16
}

func NewTree() *Tree {
    return &Tree{Item: nil, Rigth: nil, Left: nil, height: 0}
}

func InOrder(t *Tree, chTree chan Obj) {
    if t != nil {
        InOrder(t.Left, chTree)
        chTree <- t.Item
        InOrder(t.Rigth, chTree)
    }
}

// == testing ==

func TestInOrder(t *testing.T) {
    tree := NewTree()
    nums := []int{9, 7, 2, 4, 6, 10, 1, 5, 8, 3}
    for i := 0; i < len(nums); i++ {
        tree.Insert(ObjInt{nums[i]})
    }
    result := make(chan Obj, 10)
    go InOrder(tree, result)
    var previous Obj
    for obj := range result {
        fmt.Println(obj)
        if previous == nil {
            previous = obj
            continue
        }
        assertTrue(previous.Compare(obj) == -1, t,
            "Previous obj should be smaller than current object")
        previous = obj
    }
}

你不能关闭频道。你会注意到它实际上是正确打印的,然后就崩溃了

在通道上的
范围内,如下所示:

for obj := range result {
     //...
}
只有在调用
close(result)
时,循环才会退出。在这种情况下,由于递归的性质,这有点棘手。最后,我建议将调用按顺序包装到
,如下所示:

func InOrder(t *Tree, chTree chan obj) {
    inOrder(t, chTree)
    close(chTree)
}

func inOrder(t *Tree, chTree chan Obj) {
    if t != nil {
        inOrder(t.Left, chTree)
        chTree <- t.Item
        inOrder(t.Rigth, chTree)
    }
}
func顺序(t*Tree,chTree-chan-obj){
顺序(t,chTree)
关闭(红树)
}
func索引(t*树,chTree chan Obj){
如果t!=nil{
顺序(t.左,chTree)

非常感谢你,我知道我必须关闭通道,但不知道如何使用递归函数
func InOrder(t *Tree, chTree chan obj) {
    inOrder(t, chTree)
    close(chTree)
}

func inOrder(t *Tree, chTree chan Obj) {
    if t != nil {
        inOrder(t.Left, chTree)
        chTree <- t.Item
        inOrder(t.Rigth, chTree)
    }
}