为了账号安全,请及时绑定邮箱和手机立即绑定

Goroutines 执行后卡住

Goroutines 执行后卡住

Go
开满天机 2022-06-27 16:49:31
我希望有限数量的 goroutine 进行一些计算(func worker(),它进行一些计算并将结果放在通道中)。还有另一个频道,为我的工人提供“工作”。结果,我可以看到所有作业都已正确计算,但在计算执行后卡住了。package mainimport (    "bufio"    "fmt"    "os"    "net/http"    "io/ioutil"    "strings"    "time")func worker(id int, urls <- chan string, results chan<- int) {    var data string    for url := range urls {        fmt.Println("worker", id, "started  job", url)        if (strings.HasPrefix(url, "http") ||  strings.HasPrefix(url, "https")) {            resp, err := http.Get(url)            if err != nil {                fmt.Println(err)            }            defer  resp.Body.Close()            body, err := ioutil.ReadAll(resp.Body)            if err != nil {                fmt.Println(err)            }            data = string(body)        } else {            body, err := ioutil.ReadFile(url)            if err != nil {                fmt.Println(err)            }            data = string(body)        }        number := strings.Count(data, "Go")        fmt.Println("worker", id, "finished  job", url, "Number of Go is", number)        results <- number    }    return}func main() {    final_result := 0    maxNbConcurrentGoroutines := 5    numJobs := 0    urls := make(chan string)    results := make(chan int)    scanner := bufio.NewScanner(os.Stdin)    start := time.Now()    for w := 1; w <= maxNbConcurrentGoroutines; w++ {        go worker(w, urls, results)    }    for scanner.Scan() {        url := (scanner.Text())        urls <- url        numJobs += 1    }    close(urls)    for num := range results {        final_result += num    }    t := time.Now()    elapsed := t.Sub(start)    for i := 1; i <= numJobs; i++ {        one_result := <- results        final_result += one_result    }    fmt.Println("Number = ", final_result)    fmt.Println("Time = ", elapsed)    if err := scanner.Err(); err != nil {        fmt.Fprintln(os.Stderr, "error:", err)        os.Exit(1)    }}我尝试使用https://gobyexample.com/worker-pools从结果通道中提取所有值,但没有成功。我应该怎么做才能把它拆开并走得更远。以下是如何运行它的示例:
查看完整描述

1 回答

?
慕妹3242003

TA贡献1824条经验 获得超6个赞

您的程序不会返回,因为它等待结果通道的关闭状态。

https://gobyexample.com/worker-pools中,获取结果的循环是不同的:

for a := 1; a <= numJobs; a++ {
    <-results
    }

如果您想使用for num := range results您需要close(results)并确定何时调用它。

您可以在https://gobyexample.com/waitgroups查看另一个使用 WaitGroup 的示例


查看完整回答
反对 回复 2022-06-27
  • 1 回答
  • 0 关注
  • 115 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信