goroutine在“A Tour of Go”的抓取示例中没有生效

时间:2017-09-24 03:01:14

标签: go concurrency

正如在'A Tour of Go'的爬行示例中​​提到的点击,我修改了Crawl函数,并且想知道为什么'go Crawl'未能产生另一个线程,因为只发现了一个url。

我的修改有什么问题吗?

列出我的修改,如下所示,

function text(){
    if( input!="BSIT" || input!= "BSBA"|| input!="BSN") { .. }
}

1 个答案:

答案 0 :(得分:0)

在您的计划中,您没有任何同步工具可用于您的日常工作。

因此,此代码的行为未定义。 也许主要的线程将很快结束。

请记住,只有当您明确使用某种类型的util来同步go例程的执行时,main go例程才会永远阻止等待其他go例程终止。

例如频道或有用的同步工具。

让我帮忙给出一个版本。

type fetchState struct {
    mu      sync.Mutex
    fetched map[string]bool
}

func (f *fetchState) CheckAndMark(url string) bool {
    defer f.mu.Unlock()

    f.mu.Lock()
    if f.fetched[url] {
        return true
    }
    f.fetched[url] = true
    return false
}

func mkFetchState() *fetchState {
    f := &fetchState{}
    f.fetched = make(map[string]bool)
    return f
}

func CrawlConcurrentMutex(url string, fetcher Fetcher, f *fetchState) {
    if f.CheckAndMark(url) {
        return
    }

    body, urls, err := fetcher.Fetch(url)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("found: %s %q\n", url, body)
    var done sync.WaitGroup
    for _, u := range urls {
        done.Add(1)
        go func(u string) {
            defer done.Done()
            CrawlConcurrentMutex(u, fetcher, f)
        }(u) // Without the u argument there is a race
    }
    done.Wait()
    return
}

请注意sync.WaitGroup的使用情况,请参阅doc,您可以了解整个故事。