Golang 卡在 WaitGroup

我被困在自己的等待循环中,不确定为什么。该函数采用输入和输出通道,然后采用通道中的每个项目,为内容执行 http.GET 并从 html 中提取标签。


获取和抓取的过程在一个 go 例程中,我已经设置了一个等待组 (innerWait) 以确保在关闭输出通道之前我已经处理了所有内容。


   func (fp FeedProducer) getTitles(in <-chan feeds.Item,

    out chan<- feeds.Item,

    wg *sync.WaitGroup) {


    defer wg.Done()


    var innerWait sync.WaitGroup


    for item := range in {

        log.Infof(fp.c, "Incrementing inner WaitGroup.")

        innerWait.Add(1)

        go func(item feeds.Item) {

            defer innerWait.Done()

            defer log.Infof(fp.c, "Decriment inner wait group by defer.")

            client := urlfetch.Client(fp.c)

            resp, err := client.Get(item.Link.Href)

            log.Infof(fp.c, "Getting title for: %v", item.Link.Href)

            if err != nil {

                log.Errorf(fp.c, "Error retriving page. %v", err.Error())

                return

            }

            if strings.ToLower(resp.Header.Get("Content-Type")) == "text/html; charset=utf-8" {

                title := fp.scrapeTitle(resp)

                item.Title = title

            } else {

                log.Errorf(fp.c, "Wrong content type.  Received: %v from %v", resp.Header.Get("Content-Type"), item.Link.Href)

            }

            out <- item

        }(item)

    }

    log.Infof(fp.c, "Waiting for title pull wait group.")

    innerWait.Wait()

    log.Infof(fp.c, "Done waiting for title pull.")

    close(out)

}


func (fp FeedProducer) scrapeTitle(request *http.Response) string {

    defer request.Body.Close()

    tokenizer := html.NewTokenizer(request.Body)

    var titleIsNext bool

    for {

        token := tokenizer.Next()

        switch {

        case token == html.ErrorToken:

            log.Infof(fp.c, "Hit the end of the doc without finding title.")

            return ""

        case token == html.StartTagToken:

            tag := tokenizer.Token()

            isTitle := tag.Data == "title"


我可以看到我正在根据日志使用 innerWait.Wait() 命令,这也告诉我入站通道已在管道的另一侧关闭。

匿名函数中的 defer 语句似乎没有被调用,因为我在任何地方都看不到延迟日志语句。但是我终生无法解释为什么该块中的所有代码似乎都在执行。

帮助表示赞赏。


小怪兽爱吃肉
浏览 154回答 1
1回答

翻翻过去那场雪

goroutines 被困out在这一行:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;out&nbsp;<-&nbsp;item解决方法是启动一个 goroutine 来接收out.调试此类问题的一个好方法是通过向进程发送 SIGQUIT 来转储 goroutine 堆栈。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go