Golang Goroutine 泄漏

// Copyright 2012 The Go Authors.  All rights reserved.

// Use of this source code is governed by a BSD-style

// license that can be found in the LICENSE file.


// +build ignore


package main


import (

    "fmt"


    "code.google.com/p/go-tour/tree"

)


func walkImpl(t *tree.Tree, ch chan int) {

    if t == nil {

        return

    }

    walkImpl(t.Left, ch)

    ch <- t.Value

    walkImpl(t.Right, ch)

}


// Walk walks the tree t sending all values

// from the tree to the channel ch.

func Walk(t *tree.Tree, ch chan int) {

    walkImpl(t, ch)

    // Need to close the channel here

    close(ch)

}


// Same determines whether the trees

// t1 and t2 contain the same values.

// NOTE: The implementation leaks goroutines when trees are different.

// See binarytrees_quit.go for a better solution.

func Same(t1, t2 *tree.Tree) bool {

    w1, w2 := make(chan int), make(chan int)


    go Walk(t1, w1)

    go Walk(t2, w2)


    for {

        v1, ok1 := <-w1

        v2, ok2 := <-w2

        if !ok1 || !ok2 {

            return ok1 == ok2

        }

        if v1 != v2 {

            return false

        }

    }

}


func main() {

    fmt.Print("tree.New(1) == tree.New(1): ")

    if Same(tree.New(1), tree.New(1)) {

        fmt.Println("PASSED")

    } else {

        fmt.Println("FAILED")

    }


    fmt.Print("tree.New(1) != tree.New(2): ")

    if !Same(tree.New(1), tree.New(2)) {

        fmt.Println("PASSED")

    } else {

        fmt.Println("FAILED")

    }

}

它是如何做到这一点的?这个泄漏在哪里?(要测试代码,您必须在http://tour.golang.org/concurrency/8上运行它)。很困惑,希望得到一些帮助,谢谢!


繁星淼淼
浏览 192回答 2
2回答

慕标琳琳

当检测到差异时,程序停止在通道上接收。walk goroutine 会一直运行,直到它们阻止发送到通道。他们永远不会退出。这就是泄漏。

烙印99

第二种解决方案通过使用退出通道来处理泄漏。当退出通道关闭时(在 Same() 函数中),select 语句的 case 2 成功(在 walkImpl 函数中 case <-quit),函数返回。因此,程序退出后 walkImpl 函数中没有块。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go