goroutine 并发常见问题实践

程序退出时运行的 goroutine 会不会被终止

测试代码:

import (
    "time"
    "fmt"
)

func main() {
    for i := 0; i < 10; i ++ {
        go func(j int) {
            fmt.Println(j)
        }(i)
    }
    time.Sleep(3*time.Microsecond)
    return
}

运行结果:

➜  test go run ./test_goroutine.go
0
1
2
3
4
5
6
7
8
9
➜  test go run ./test_goroutine.go
5
4
6
➜  test go run ./test_goroutine.go
➜  test go run ./test_goroutine.go

结论:主程序结束时还在运行中的 goroutine 也会终止。

怎样让主程序等待所有 goroutine 退出:

  • 使用管道 channel,适用于单个 goroutine

    func main() {
        ch := make(chan int)
        go func(c chan int){
            time.Sleep(time.Second * 3)
            fmt.Println("goroutine 即将结束。")
            c <- 1
        }(ch)
    
        fmt.Println("主程序即将结束。")
    
        <- ch
    
        fmt.Println("主程序退出。")
    }
    

    运行结果:

    主程序即将结束。
    goroutine 即将结束。
    主程序退出。
    
  • 使用 WaitGroup

    import (
        "fmt"
        "sync"
    )
    
    func main() {
        wg := sync.WaitGroup{}
    
        // wg.Add(10)
        for i := 0; i < 10; i++ {
            wg.Add(1)
            go func(j int, wg *sync.WaitGroup) {
                defer wg.Done()
                fmt.Printf("goroutine %d 即将退出。\n", j + 1)
            }(i, &wg) // 此处注意使用指针传递,否则 goroutine 中的 wg 为新的对象
        }
    
        fmt.Println("主程序即将退出。")
        wg.Wait()
        fmt.Println("主程序退出。")
    }
    

    运行结果:

    主程序即将退出。
    goroutine 4 即将退出。
    goroutine 1 即将退出。
    goroutine 2 即将退出。
    goroutine 3 即将退出。
    goroutine 7 即将退出。
    goroutine 5 即将退出。
    goroutine 6 即将退出。
    goroutine 9 即将退出。
    goroutine 10 即将退出。
    goroutine 8 即将退出。
    主程序退出。
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容