douba9425 2017-03-12 20:28 采纳率: 100%
浏览 242
已采纳

防止main()函数在Golang中的goroutine完成之前终止

Have loook at this contrived example:

package main

import "fmt"

func printElo() {
    fmt.Printf("Elo
")
}

func printHello() {
    fmt.Printf("Hello
")
}

func main() {
    fmt.Printf("This will print.")
    i := 0
    for i < 10 {
        go printElo()
        go printHello()
        i++
    }
}

The output of this program would be just "This will print". Output of goroutines printElo() and printHello will not be emitted because, I guess, the main() function thread will finish before the goroutines have a chance to even start executing.

What is the idiomatic way to make similar code work in Golang and not terminate prematurely?

  • 写回答

4条回答 默认 最新

  • dousuitang5239 2017-03-12 20:51
    关注

    Simplest, cleanest and "scalable" way to do it is to use a sync.WaitGroup:

    var wg = &sync.WaitGroup{}
    
    func printElo() {
        defer wg.Done()
        fmt.Printf("Elo
    ")
    }
    
    func printHello() {
        defer wg.Done()
        fmt.Printf("Hello
    ")
    }
    
    func main() {
        fmt.Printf("This will print.")
        i := 0
        for i < 10 {
            wg.Add(1)
            go printElo()
            wg.Add(1)
            go printHello()
            i++
        }
        wg.Wait()
    }
    

    Output (try it on the Go Playground):

    This will print.Hello
    Elo
    Hello
    Elo
    Hello
    Elo
    Hello
    Elo
    Hello
    Elo
    Hello
    Elo
    Hello
    Elo
    Hello
    Elo
    Hello
    Elo
    Hello
    Elo
    

    Simple "rules" to follow when doing it with sync.WaitGroup:

    • call WaitGroup.Add() in the "original" goroutine (that starts a new) before the go statement
    • recommended to call WaitGroup.Done() deferred, so it gets called even if the goroutine panics
    • if you want to pass WaitGroup to other functions (and not use a global variable), you must pass a pointer to it, else the WaitGroup (which is a struct) would be copied, and the Done() method called on the copy wouldn't be observed on the original
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?