是的,它看起来像StackOverflow上最重复的问题之一,但请花几分钟时间回答这个问题。一个通道关闭了,但所有的goroutines都睡着了 - 死锁
func _Crawl(url string, fetcher Fetcher, ch chan []string) {
if store.Read(url) == true {
return
} else {
store.Write(url)
}
body, urls, err := fetcher.Fetch(url)
if err != nil {
fmt.Printf("not found: %s\n", url)
}
fmt.Printf("found: %s %q\n", url, body)
ch <- urls
}
func Crawl(url string, fetcher Fetcher) {
UrlChannel := make(chan []string, 4)
go _Crawl(url, fetcher, UrlChannel)
for urls, ok := <- UrlChannel; ok; urls, ok = <- UrlChannel{
for _, i := range urls {
go _Crawl(i, fetcher, UrlChannel)
}
}
close(UrlChannel) //The channel is closed.
}
func main() {
Crawl("http://golang.org/", fetcher)
}
我在循环结束后关闭通道。该程序返回正确的结果,但在最后引发错误:
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.Crawl(0x113a2f, 0x12, 0x1800d0, 0x10432220)
/tmp/sandbox854979773/main.go:55 +0x220
main.main()
/tmp/sandbox854979773/main.go:61 +0x60
我的goroutines有什么问题?
死锁发生是因为调用'close'永远不会到达。只有在通道关闭时,通道接收中的“ok”才会为false,因此执行会停留在该回路中。你应该考虑使用范围循环(http://dave.cheney.net/2014/03/19/channel-axioms)。如果你对重新设计这个设计有点不错,像这样的东西可以作为一个提示:https://play.golang.org/p/aiuiyueyzB – abhink
是的,关闭频道不可达,但这不是问题的根源这里并没有,执行将卡住只有无限的网址 –