我希望有限数量的 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 的示例
- 1 回答
- 0 关注
- 115 浏览
添加回答
举报
0/150
提交
取消