【问题标题】:Why does my concurrent function exit prematurely in Go? [duplicate]为什么我的并发函数在 Go 中过早退出? [复制]
【发布时间】:2015-09-02 00:42:25
【问题描述】:

我正在浏览 Go Bootcamp,现在正在阅读 Go Concurrency 章节。之前编程没用过并发,看不懂这个程序的输出:

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")
}

输出:

hello
world
hello

Program exited.

有人可以解释为什么“世界”没有像“你好”那样打印两次吗?也许阐明使用并发的想法?

注意,去游乐场链接here

【问题讨论】:

    标签: concurrency go


    【解决方案1】:

    当 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 完成后立即干净地退出。

    例如(playground):

    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
    }
    

    【讨论】:

      猜你喜欢
      • 2011-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 2021-10-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多