我是一位高丽的新手,目前正在练习:网络爬虫工作。
我只是把关键字'go‘放在每个调用func的地方,并希望它可以并行化,但是fmt.Printf不工作,什么也不打印。除了这个代码,在原始代码上没有其他任何改变。有人愿意帮我吗?
func Crawl(url string, depth int, fetcher Fetcher) {
// TODO: Fetch URLs in parallel.
// TODO: Don't fetch the same URL twice.
// This implementation doesn't do either:
if depth <= 0 {
return
}
body, urls, err := fetcher.Fetch(url)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("found: %s %q\n", url, body)
for _, u := range urls {
go Crawl(u, depth-1, fetcher)
}
return
}
func main() {
go Crawl("https://golang.org/", 4, fetcher)
}发布于 2019-02-13 03:49:53
根据等级库
程序执行首先初始化主包,然后调用函数main。当该函数调用返回时,程序将退出。它不会等待其他的(非主要的)峡谷完成。
因此,您必须显式地等待另一个goroutine以main()函数结尾。
一种方法是简单地在time.Sleep()函数的末尾添加main(),直到您认为另一个goroutine结束为止(例如,在本例中可能是1秒)。
更干净的方法是使用sync.WaitGroup,如下所示:
func Crawl(wg *sync.WaitGroup, url string, depth int, fetcher Fetcher) {
defer wg.Done()
if depth <= 0 {
return
}
body, urls, err := fetcher.Fetch(url)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("found: %s %q\n", url, body)
for _, u := range urls {
wg.Add(1)
go Crawl(wg, u, depth-1, fetcher)
}
return
}
func main() {
wg := &sync.WaitGroup{}
wg.Add(1)
// first call does not need to be goroutine since its subroutine is goroutine.
Crawl(wg, "https://golang.org/", 4, fetcher)
//time.Sleep(1000 * time.Millisecond)
wg.Wait()
}此代码将计数器存储在WaitGroup中,使用wg.Add()递增计数器,使用wg.Done()递减计数器,并等待直到使用wg.Wait()的计数器变为零。
https://stackoverflow.com/questions/54661972
复制相似问题