猿问

Goroutines 执行后卡住

我希望有限数量的 goroutine 进行一些计算(func worker(),它进行一些计算并将结果放在通道中)。还有另一个频道,为我的工人提供“工作”。结果,我可以看到所有作业都已正确计算,但在计算执行后卡住了。


package main

import (

    "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从结果通道中提取所有值,但没有成功。我应该怎么做才能把它拆开并走得更远。以下是如何运行它的示例:


开满天机
浏览 116回答 1
1回答

慕妹3242003

您的程序不会返回,因为它等待结果通道的关闭状态。在https://gobyexample.com/worker-pools中,获取结果的循环是不同的:for&nbsp;a&nbsp;:=&nbsp;1;&nbsp;a&nbsp;<=&nbsp;numJobs;&nbsp;a++&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;<-results &nbsp;&nbsp;&nbsp;&nbsp;}如果您想使用for num := range results您需要close(results)并确定何时调用它。您可以在https://gobyexample.com/waitgroups查看另一个使用 WaitGroup 的示例
随时随地看视频慕课网APP

相关分类

Go
我要回答