【发布时间】:2020-09-12 03:52:58
【问题描述】:
我只是在写一个简单的 Go 管道,目标是获取 url 并打印状态。
在 fetchUrl 上,我需要关闭 channel 来通知 main,不会有数据传入,所以释放 main go 例程。但是我不能在循环后真正关闭 fetchurl 函数上的频道,因为它会为时过早。我不想在应用程序中添加等待组,因为目前我的整个目标是了解渠道。
在 fetchurl 函数中,调用 2 的通道只是为了确保一次只有 2 个作业。
package main
import (
"fmt"
"net/http"
"os"
)
func gen(val []string) <-chan string {
out := make(chan string, len(val))
for _, val := range val {
out <- val
}
close(out)
return out
}
func fetchUrl(in <-chan string) <-chan string {
out := make(chan string)
two := make(chan struct{}, 2)
fmt.Println("blocked")
for url := range in {
two <- struct{}{}
go fetchWorker(url, two, out)
}
return out
}
func fetchWorker(url string, two chan struct{}, out chan string) {
res, err := http.Get("https://" + url)
if err != nil {
panic(err)
}
<-two
out <- fmt.Sprintf("[%d] %s\n", res.StatusCode, url)
}
func main() {
for val := range fetchUrl(gen(os.Args[1:])) {
fmt.Println(val)
}
}
【问题讨论】:
-
"我不想在应用程序中添加等待组。"这是适当的解决方案。等待所有 fetchWorker 调用完成,然后关闭通道。