https://github.com/goinaction/code/tree/master/chapter2/sample,
这个是第二章的代码。个人还是不太能理解为什么在search/search.go上面可以通过一个go routine去等待waitGroup.wait(),而不用在run方法里面在原来的goroutine中进行waitGroup.wait0().因为之前写的代码以node和python为主,不太能理解为什么不用在主上面等待回调
更多评论
你说的是这一段吧:
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