[英]Why does the goroutine only run once as part of a waitgroup
func check(name string) string {
resp, err := http.Get(endpoint + name)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
panic(err)
}
return string(body)
}
func worker(name string, wg *sync.WaitGroup, names chan string) {
defer wg.Done()
var a = check(name)
names <- a
}
func main() {
names := make(chan string)
var wg sync.WaitGroup
for i := 1; i <= 5; i++ {
wg.Add(1)
go worker("www"+strconv.Itoa(i), &wg, names)
}
fmt.Println(<-names)
}
预期结果将是 5 个结果,但只有一个执行并且过程结束。 有什么我想念的吗? go 的新功能。 端点是返回 json 的通用 API
你启动了 5 个 goroutine,但只读取了一个的输入。 此外,您不会等待 goroutines 结束。
// If there are only 5 goroutines unconditionally, you don't need the wg
for i := 1; i <= 5; i++ {
go worker("www"+strconv.Itoa(i), names)
}
for i:=1;i<=5;i++ {
fmt.Println(<-names)
}
然而,如果你不知道你在等待多少个 goroutine,那么等待组是必要的。
for i := 1; i <= 5; i++ {
wg.Add(1)
go worker("www"+strconv.Itoa(i), &wg, names)
}
// Read from the channel until it is closed
done:=make(chan struct{})
go func() {
for x:=range names {
fmt.Println(x)
}
// Signal that println is completed
close(done)
}()
// Wait for goroutines to end
wg.Wait()
// Close the channel to terminate the reader goroutine
close(names)
// Wait until println completes
<-done
您正在启动 5 个 goroutine,但仅从names
通道读取一次。
fmt.Println(<-names)
一旦第一个通道读取完成, main()
就会退出。
这意味着一切都在有时间执行之前停止。
要了解有关通道的更多信息,请参阅Dave Cheney的“轻松实现并发”:
- 如果您必须等待操作的结果,那么您自己做会更容易。
- 以您获得它们的相反顺序释放锁和信号量。
- 通道不是文件或 sockets 之类的资源,您无需关闭它们即可释放它们。
- 准备好使用信号量时获取信号量。
- 避免混合匿名函数和 goroutines
- 在你启动一个 goroutine 之前,总是知道它何时以及如何停止
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.