防止 main() 函数在 Golang 中的 goroutines 完成之前终止 [英] Prevent the main() function from terminating before goroutines finish in Golang

查看:29
本文介绍了防止 main() 函数在 Golang 中的 goroutines 完成之前终止的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看看这个人为的例子:

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++
    }
}

这个程序的输出将只是这将打印".goroutines printElo()printHello 的输出不会被发出,因为我猜,main() 函数线程将在 goroutines 之前完成甚至有机会开始执行.

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.

让类似代码在 Golang 中工作并且不会过早终止的惯用方法是什么?

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

推荐答案

最简单、最干净和可扩展"方法是使用 sync.WaitGroup:

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

输出(在 Go Playground 上试试):

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

简单的规则"使用 sync.WaitGroup 执行此操作时要遵循:

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

  • 调用 WaitGroup.Add()原件"在 go 语句之前的 goroutine(开始一个新的)莉>
  • 建议调用WaitGroup.Done() 延迟,因此即使 goroutine 发生恐慌,它也会被调用
  • 如果你想将 WaitGroup 传递给其他函数(而不是使用包级变量),你必须传递一个指向它的指针,否则 WaitGroup(这是struct) 将被复制,并且在副本上调用的 Done() 方法不会在原始文件上观察到
  • 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 package level 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

这篇关于防止 main() 函数在 Golang 中的 goroutines 完成之前终止的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆