Goroutine没有按预期运行

Goroutine没有按预期运行,go,Go,我仍在学习Go,并在做链接的网络爬虫练习。我实现的主要部分如下。其他部分保持不变,可以在链接中找到 //爬网使用抓取器进行递归爬网 //以url开头的页面,最大深度。 func Crawlurl字符串,深度int,获取程序{ //TODO:并行获取URL。 //TODO:不要获取同一URL两次。 //此实现既不执行以下操作,也不执行以下操作: 如果深度您的程序很可能在爬网程序完成其工作之前退出。一种方法是爬网程序有一个等待组,等待其所有子爬网程序完成。例如 import "sync" // C

我仍在学习Go,并在做链接的网络爬虫练习。我实现的主要部分如下。其他部分保持不变,可以在链接中找到

//爬网使用抓取器进行递归爬网 //以url开头的页面,最大深度。 func Crawlurl字符串,深度int,获取程序{ //TODO:并行获取URL。 //TODO:不要获取同一URL两次。 //此实现既不执行以下操作,也不执行以下操作:
如果深度您的程序很可能在爬网程序完成其工作之前退出。一种方法是爬网程序有一个等待组,等待其所有子爬网程序完成。例如

import "sync"

// Crawl uses fetcher to recursively crawl
// pages starting with url, to a maximum of depth.
func Crawl(url string, depth int, fetcher Fetcher, *wg sync.WaitGroup) {
    defer func() {
        // If the crawler was given a wait group, signal that it's finished
        if wg != nil {
            wg.Done()
        }
    }()

    if depth <= 0 {
        return
    }

    _, urls, err := fetcher.Fetch(url)
    cache.Set(url)
    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Printf("found: %s %q\n", url, body)

    var crawlers sync.WaitGroup
    for _, u := range urls {
        if cache.Get(u) == false {
            fmt.Println("Next:", u)
            crawlers.Add(1)
            go Crawl(u, depth-1, fetcher, &crawlers)
        }
    }
    crawlers.Wait() // Waits for its sub-crawlers to finish

    return 
}

func main() {
   // The root does not need a WaitGroup
   Crawl("http://example.com/index.html", 4, nil)
}

您是否在爬网功能中添加了go Crawl?最有可能的是,您的程序在爬网程序完成工作之前退出。查看@Niwatori您检查的答案显然是错误的:如果您像在代码中那样添加GoRoutine,则有竞争条件,这不太难修复,但需要一些修改effort@zerkms你能告诉我埃拉博拉吗有一点?我猜变量u导致了竞争条件,但不是很确定。在非并发代码中使用WaitGroup有什么意义?如果删除它,什么都不会改变。我假设它应该是循环中的go-Crawlu、depth-1、fetcher和crawlers,但它确实解决了问题。谢谢!@Niwatori如果您添加go-there,那么这段代码就可以了很容易出现竞态条件。所以这并不能解决问题。@Tristian:现在,在您修改代码之后-在并发的wg.Add和wg.Wait调用周围很容易出现竞态条件。我错了,这里没有竞态条件,我道歉。
found: https://golang.org/ "The Go Programming Language"
Next: https://golang.org/pkg/
Next: https://golang.org/cmd/
import "sync"

// Crawl uses fetcher to recursively crawl
// pages starting with url, to a maximum of depth.
func Crawl(url string, depth int, fetcher Fetcher, *wg sync.WaitGroup) {
    defer func() {
        // If the crawler was given a wait group, signal that it's finished
        if wg != nil {
            wg.Done()
        }
    }()

    if depth <= 0 {
        return
    }

    _, urls, err := fetcher.Fetch(url)
    cache.Set(url)
    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Printf("found: %s %q\n", url, body)

    var crawlers sync.WaitGroup
    for _, u := range urls {
        if cache.Get(u) == false {
            fmt.Println("Next:", u)
            crawlers.Add(1)
            go Crawl(u, depth-1, fetcher, &crawlers)
        }
    }
    crawlers.Wait() // Waits for its sub-crawlers to finish

    return 
}

func main() {
   // The root does not need a WaitGroup
   Crawl("http://example.com/index.html", 4, nil)
}