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

go lang,为什么从不调用 go 例程函数

go lang,为什么从不调用 go 例程函数

Go
浮云间 2021-09-27 21:09:58
package mainimport (    "fmt"    //"runtime")func say(s string) {    for i := 0; i < 5; i++ {        //runtime.Gosched()        fmt.Println(s)    }}func main() {    go say("world") // create a new goroutine    say("hello") // current goroutine}为什么结果是:你好你好你好你好你好为什么没有world?答案:(编辑:)如果我这样做,现在很好:package mainimport (    "fmt"    "runtime")func say(s string) {    for i := 0; i < 5; i++ {        //runtime.Gosched()        fmt.Println(s)    }}func main() {    go say("world") // create a new goroutine    runtime.Gosched()    say("hello") // current goroutine}
查看完整描述

3 回答

?
千万里不及你

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

您只是遇到了时间问题,因为您没有“协调”您的 go 例程。处理这个问题的常用方法是使用守卫。我不时看到使用频道和阻塞选择的另一个选项。等待守卫的实现看起来像这样;


func main() {

    wg := sync.WaitGroup{}

    wg.Add(1)

    go say("world") // create a new goroutine


    wg.Add(1)

    say("hello") // current goroutine

    wg.Wait()

}

虽然通道选项(在这个例子中实际上并不有趣或有用)更像是这样的;


 func main() {

    done := make(chan bool)

    go say("world", done) // create a new goroutine


    say("hello", done) // current goroutine


    select {

        case fin := <- done:

           //on finished

           return

    }

}


func say(s string, chan bool) {

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

    fmt.Println(s)

   }

   done <- true

}

但是,在上面的示例中,第一个调用完成将允许程序完成执行。为了确保两者都完成,您必须将不同的通道传递给每个通道,并对两者进行阻塞读取。当你的 goroutine 正在做真正的工作并且你想要从它们中聚合数据或者需要更复杂的协调(比如根据以前的结果产生新的 goroutines 等)时,这更像是我会使用的一种模式。


查看完整回答
反对 回复 2021-09-27
?
一只斗牛犬

TA贡献1784条经验 获得超2个赞

您不允许 goroutine 在main()退出之前运行。


即使第二次调用say块(简短地),也不能保证第一个 goroutine 可以运行。您需要等待两者都返回,这通常是通过 WaitGroup 完成的


var wg sync.WaitGroup


func say(s string) {

    defer wg.Done()

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

        //runtime.Gosched()

        fmt.Println(s)

    }

}


func main() {

    wg.Add(1)

    go say("world") // create a new goroutine


    wg.Add(1)

    say("hello") // current goroutine

    wg.Wait()

}


查看完整回答
反对 回复 2021-09-27
?
潇潇雨雨

TA贡献1833条经验 获得超4个赞

这是因为主要的 goroutine 退出得太早了。当主 goroutine 退出时,进程将退出,因此其他 goroutine 没有机会运行。如果您希望 goroutines 运行,请保持主程序运行足够长的时间。


package main


import (

    "fmt"

    "runtime"

)


func say(s string) {

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

        fmt.Println(s)

    }

}


func main() {

    go say("world") // create a new goroutine

    runtime.Gosched()


    say("hello") // current goroutine

    time.Sleep(1 * time.Second) // this line

}


查看完整回答
反对 回复 2021-09-27
  • 3 回答
  • 0 关注
  • 147 浏览
慕课专栏
更多

添加回答

举报

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