Golang防止等待组永远阻止

时间:2016-07-05 20:09:16

标签: go

我是Golang的新手并拥有以下代码。我希望能够在新的Goroutine中获取不同问题标签的问题。但我对同步等待组感到困惑。

我的程序似乎永远阻止,并且永远不会到达底部的print语句。有人能指出我正确的方向吗?

我尝试使用此处文档中相当直接的示例进行构建https://golang.org/pkg/sync/#WaitGroup     包主要

import (
    "fmt"
    "log"
    "os"
    "sync"

    "github.com/PuerkitoBio/goquery"
)

type question struct {
    lang, text, url string
}

var url string = "http://stackoverflow.com/questions/tagged/"

func scrapePage(url string) *goquery.Document {
    doc, err := goquery.NewDocument(url)
    if err != nil {
        log.Fatal(err)
    }
    return doc
}

func getQuestions(lang string, ch chan<- question, wg sync.WaitGroup) {
    defer wg.Done()
    doc := scrapePage(url + lang)
    doc.Find(".summary .question-hyperlink").Each(func(i int, s *goquery.Selection) {
        url, _ := s.Attr("href")
        text := s.Text()
        ch <- question{lang, text, url}
    })
}

func main() {
    tags := os.Args[1:]

    var wg sync.WaitGroup
    wg.Add(len(tags))

    ch := make(chan question)
    for index := range tags {
        lang := tags[index]
        go getQuestions(lang, ch, wg)
    }

    go func() {
        for i := range ch {
            fmt.Println(i)
        }
    }()

    wg.Wait()

    // Never reached :(
    fmt.Println("Done")

}

更新 在有人指出我错误地传递了wg.WaitGroup的副本

之后,仍然没有运气
package main

import (
    "fmt"
    "log"
    "os"
    "sync"

    "github.com/PuerkitoBio/goquery"
)

type question struct {
    lang, text, url string
}

var url string = "http://stackoverflow.com/questions/tagged/"

var wg sync.WaitGroup

func main() {
    tags := os.Args[1:]

    wg.Add(len(tags))

    ch := make(chan question)
    for index := range tags {
        lang := tags[index]
        go getQuestions(lang, ch)
    }

    wg.Wait()
    fmt.Println("After WAIT")
    close(ch)

    for i := range ch {
        fmt.Println(<-ch, i)
    }
    ch = nil
    fmt.Println("Done")

}

func getQuestions(lang string, ch chan question) {
    doc := scrapePage(url + lang)
    doc.Find(".summary .question-hyperlink").Each(func(i int, s *goquery.Selection) {
        url, _ := s.Attr("href")
        text := s.Text()
        ch <- question{lang, text, url}
    })
    wg.Done()
}

func scrapePage(url string) *goquery.Document {
    doc, err := goquery.NewDocument(url)
    if err != nil {
        log.Fatal(err)
    }
    return doc
}

0 个答案:

没有答案