go编程实战的问题

ray1888 · 2017-12-06 15:13:31 · 1111 次点击

求熟悉go的大神解答一下

#1
更多评论

我觉得可以尝试waitGroup.wait()放到主方面里面,运行一下,看一下有没有什么差异来理解

#2

你说的是这一段吧:

go func() {
    // Wait for everything to be processed.
    waitGroup.Wait()

    // Close the channel to signal to the Display
    // function that we can exit the program.
    close(results)
}()

// Start displaying results as they are available and
// return after the final result is displayed.
Display(results)

这段go routine启动一个 monitor,等待上面所有的routine执行完成,然后关闭results. Display(results)也同时执行,Display方法是这样的:

func Display(results chan *Result) {
    // The channel blocks until a result is written to the channel.
    // Once the channel is closed the for loop terminates.
    for result := range results {
        log.Printf("%s:\n%s\n\n", result.Field, result.Content)
    }
}

一旦results关闭,for loop就结束。 这时Display方法就执行完毕,run方法也结束。

如果在run中直接去进行waitGroup.Wait(),就变成了这样:

    waitGroup.Wait()
    close(results)
    Display(results)

,那就会死锁,因为results是chan类型,上面的三个语句顺序执行,results只有进,没有出了。 而如果是这样: Display(results) waitGroup.Wait() close(results)

也会造成死锁,因为Display(results)一直在执行,等待results关闭,但是因为是顺序执行的,所以results无法关闭,所以会在最后死锁。 如果是这样:

    go func(){
            Display(results)
    }()
    waitGroup.Wait()
    close(results)

因为如果close了results,那run方法就直接退出,而如果Display没有执行完成,也会因为run退出而结束。不是好方法。

也许还有别的写法去进行执行,我个人认为例子中开个goroutine去监视的写法就很不错。

#3