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

等待 go 例程完成的正确方法

等待 go 例程完成的正确方法

Go
胡子哥哥 2021-08-16 19:26:57
我想知道在退出程序之前等待 goroutine 完成的正确方法是什么。阅读其他一些答案似乎 bool chan 可以解决问题,如Playground 链接func do_stuff(done chan bool) {    fmt.Println("Doing stuff")    done <- true}func main() {    fmt.Println("Main")    done := make(chan bool)    go do_stuff(done)    <-done    //<-done}我在这里有两个问题:为什么 <- done 完全有效?如果我取消对最后一行的注释会发生什么?我有一个死锁错误。这是因为通道是空的并且没有其他函数向它发送值吗?
查看完整描述

2 回答

?
BIG阳

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

为什么是<- done作品?

  • 它起作用是因为运行时检测到您正在向其他地方的通道写入内容。

如果我取消对最后一行的注释会发生什么?

  • 运行时足够聪明,知道没有其他东西被写入并且它会死锁。

奖励,如果您的内存非常有限,您可以使用done := make(chan struct{})and done <- struct{}{}struct{}保证使用 0 内存。


查看完整回答
反对 回复 2021-08-16
?
饮歌长啸

TA贡献1951条经验 获得超3个赞

收听 channel<- done是一个阻塞操作,所以你的程序不会继续,直到发送 true 或 false ,即done <- true。


根据情况,您的问题可以有几个不同的答案。


例如,假设您想要并行化一系列需要很长时间的函数调用。


我会为此使用该sync软件包


package main


import (

    "fmt"

    "sync"

    "time"

)


func main() {

    var wg sync.WaitGroup

    for i := 0; i < 10; i++ {

        wg.Add(1)

        go func() {

            longOp()

            wg.Done()

        }()

    }

    // will wait until wg.Done is called 10 times

    // since we made wg.Add(1) call 10 times

    wg.Wait()

}


func longOp() {

    time.Sleep(time.Second * 2)

    fmt.Println("long op done")

}


查看完整回答
反对 回复 2021-08-16
  • 2 回答
  • 0 关注
  • 231 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信