Prevent the main() function from terminating before goroutines finish in Golang

前端 未结 4 985
悲哀的现实
悲哀的现实 2020-11-28 15:47

Have loook at this contrived example:

package main

import \"fmt\"

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

func printHello() {
    fmt.Printf(\"Hel         


        
4条回答
  •  孤独总比滥情好
    2020-11-28 16:19

    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\n")
    }
    
    func printHello() {
        defer wg.Done()
        fmt.Printf("Hello\n")
    }
    
    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

提交回复
热议问题