首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >练习: Web Crawler -打印不工作

练习: Web Crawler -打印不工作
EN

Stack Overflow用户
提问于 2019-02-13 03:17:04
回答 1查看 163关注 0票数 0

我是一位高丽的新手,目前正在练习:网络爬虫工作。

我只是把关键字'go‘放在每个调用func的地方,并希望它可以并行化,但是fmt.Printf不工作,什么也不打印。除了这个代码,在原始代码上没有其他任何改变。有人愿意帮我吗?

代码语言:javascript
复制
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)
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-13 03:49:53

根据等级库

程序执行首先初始化主包,然后调用函数main。当该函数调用返回时,程序将退出。它不会等待其他的(非主要的)峡谷完成。

因此,您必须显式地等待另一个goroutine以main()函数结尾。

一种方法是简单地在time.Sleep()函数的末尾添加main(),直到您认为另一个goroutine结束为止(例如,在本例中可能是1秒)。

更干净的方法是使用sync.WaitGroup,如下所示:

代码语言:javascript
复制
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://play.golang.org/p/WqQBqe6iFLp

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54661972

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档