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

我想知道在退出程序之前等待 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 完全有效?


如果我取消对最后一行的注释会发生什么?我有一个死锁错误。这是因为通道是空的并且没有其他函数向它发送值吗?


胡子哥哥
浏览 232回答 2
2回答

BIG阳

为什么是<- done作品?它起作用是因为运行时检测到您正在向其他地方的通道写入内容。如果我取消对最后一行的注释会发生什么?运行时足够聪明,知道没有其他东西被写入并且它会死锁。奖励,如果您的内存非常有限,您可以使用done := make(chan struct{})and&nbsp;done <- struct{}{},struct{}保证使用 0 内存。

饮歌长啸

收听 channel<- done是一个阻塞操作,所以你的程序不会继续,直到发送 true 或 false ,即done <- true。根据情况,您的问题可以有几个不同的答案。例如,假设您想要并行化一系列需要很长时间的函数调用。我会为此使用该sync软件包package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "sync"&nbsp; &nbsp; "time")func main() {&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; for i := 0; i < 10; i++ {&nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; longOp()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wg.Done()&nbsp; &nbsp; &nbsp; &nbsp; }()&nbsp; &nbsp; }&nbsp; &nbsp; // will wait until wg.Done is called 10 times&nbsp; &nbsp; // since we made wg.Add(1) call 10 times&nbsp; &nbsp; wg.Wait()}func longOp() {&nbsp; &nbsp; time.Sleep(time.Second * 2)&nbsp; &nbsp; fmt.Println("long op done")}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go