duanlaican1849
duanlaican1849
2015-03-04 14:38

Go-tour解决方案中binarytrees_quit.go中退出通道的目的是什么?

  • IT行业问题
  • 计算机技术
  • it技术
  • 编程语言问答
  • 互联网问答
已采纳

I don't quite understand the purpose of quit channel variable in binarytrees_quit.go. Or, am I missing the important point here. I can understand that receiver can send value to quit to tell the go routine to return or exit. But I don't think that it's the case here. Is it just to make sure that Walk routines stick around till Same finishes the execution? Won't go routine stick around just because channels are not buffered. Even if this is the case, that does not make any sense. Please help me to understand.

Thanks in advance!

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

1条回答

  • doubeng1278 doubeng1278 6年前

    You can see that approached detailed in "Go for gophers - GopherCon closing keynote - 25 April 2014 - Andrew Gerrand "

    Stopping early
    Add a quit channel to the walker so we can stop it mid-stride.

    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)
        }
    }
    

    Create a quit channel and pass it to each walker.
    By closing quit when the Same exits, any running walkers are terminated.

    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
            }
        }
    }
    

    Andrew adds:

    Why not just kill the goroutines?

    Goroutines are invisible to Go code. They can't be killed or waited on.
    You have to build that yourself.

    There's a reason:

    As soon as Go code knows in which thread it runs you get thread-locality.
    Thread-locality defeats the concurrency model
    .

    • Channels are just values; they fit right into the type system.
    • Goroutines are invisible to Go code; this gives you concurrency anywhere.

    Less is more.

    点赞 评论 复制链接分享

为你推荐