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

为什么 goroutine 只作为等待组的一部分运行一次

为什么 goroutine 只作为等待组的一部分运行一次

Go
叮当猫咪 2022-06-27 09:32:48
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 个结果,但只有一个执行并且过程结束。有什么我想念的吗?新的去。端点是返回 json 的通用 API
查看完整描述

2 回答

?
慕码人8056858

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

你启动了 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


查看完整回答
反对 回复 2022-06-27
?
慕少森

TA贡献2019条经验 获得超9个赞

您正在启动 5 个 goroutine,但仅从频道读取names一次。

fmt.Println(<-names)

一旦第一个通道读取完成,就main()退出。
这意味着一切都在有时间执行之前停止。

要了解有关通道的更多信息,请参阅Dave Cheney的“轻松实现并发” :

  • 如果您必须等待操作的结果,那么您自己做会更容易。

  • 以您获得它们的相反顺序释放锁和信号量。

  • 通道不是文件或套接字之类的资源,您无需关闭它们即可释放它们。

  • 准备好使用信号量时获取信号量。

  • 避免混合匿名函数和 goroutines

  • 在你启动一个 goroutine 之前,总是知道它何时以及如何停止


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

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号