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

为什么我的并发函数在 Go 中过早退出?

为什么我的并发函数在 Go 中过早退出?

Go
牛魔王的故事 2021-10-18 10:21:45
我正在浏览 Go Bootcamp 并且正在阅读 Go Concurrency 一章。我之前在编程中从未使用过并发,不理解这个程序的输出:package mainimport (    "fmt"    "time")func say(s string) {    for i := 0; i < 2; i++ {        time.Sleep(100 * time.Millisecond)        fmt.Println(s)    }}func main() {    go say("world")    say("hello")}输出:helloworldhelloProgram exited.有人可以解释为什么“世界”不像“你好”那样打印两次吗?也许阐明使用并发的想法?请注意,此处为Go Playground 链接。
查看完整描述

1 回答

?
aluckdog

TA贡献1847条经验 获得超7个赞

当 main 返回时,Go 程序退出。在这种情况下,您的程序在退出之前不会等待最终的“世界”在另一个 goroutine 中打印出来。


以下代码(playground)将确保 main 永远不会退出,从而允许其他 goroutine 完成。


package main


import (

    "fmt"

    "time"

)


func say(s string) {

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

        time.Sleep(100 * time.Millisecond)

        fmt.Println(s)

    }

}


func main() {

    go say("world")

    say("hello")

    select{}

}

您可能已经注意到,这会导致死锁,因为程序无法继续前进。您可能希望添加一个通道或一个 sync.Waitgroup 以确保程序在其他 goroutine 完成后立即干净地退出。


例如(游乐场):


func say(s string, ch chan<- bool) {

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

        time.Sleep(100 * time.Millisecond)

        fmt.Println(s)

    }


    if ch != nil {

        close(ch)

    }

}


func main() {

    ch := make(chan bool)

    go say("world", ch)

    say("hello", nil)

    // wait for a signal that the other goroutine is done

    <-ch

}


查看完整回答
反对 回复 2021-10-18
  • 1 回答
  • 0 关注
  • 141 浏览
慕课专栏
更多

添加回答

举报

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