我被困在自己的等待循环中,不确定为什么。该函数采用输入和输出通道,然后采用通道中的每个项目,为内容执行 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 语句似乎没有被调用,因为我在任何地方都看不到延迟日志语句。但是我终生无法解释为什么该块中的所有代码似乎都在执行。帮助表示赞赏。
1 回答
翻翻过去那场雪
TA贡献2065条经验 获得超14个赞
goroutines 被困out
在这一行:
out <- item
解决方法是启动一个 goroutine 来接收out
.
调试此类问题的一个好方法是通过向进程发送 SIGQUIT 来转储 goroutine 堆栈。
- 1 回答
- 0 关注
- 153 浏览
添加回答
举报
0/150
提交
取消