Go语言 如何将WaitGroup传递给顺序函数调用?

ar7v8xwq  于 2022-12-07  发布在  Go
关注(0)|答案(1)|浏览(147)

我有一个函数,它可以在单独的goroutine中被顺序调用或并发调用。
我想确保函数在主goroutine完成之前执行完毕,所以我传递了 * sync.WaitGroup参数给函数,现在,在某些地方函数是顺序调用的。
我可以将nil waitGroup传递给函数,如下所示:

func my_func(wg *sync.WaitGroup){
   if wg != nil{
   defer wg.Done()
   }
   // do the task
}

func main(){
my_func(nil) // sequential call

wg := sync.WaitGroup{}
wg.Add(1)
go my_func(&wg)  // concurrent call
wg.Wait()
}

有没有更好的方法来实现这一点?

vxf3dgd4

vxf3dgd41#

你的my_func()不应该知道/不应该关心它是如何被执行的(不管是不是在一个新的goroutine中),所以你不应该为此传递wg。不要强制并发或非并发地使用你的API,让你的包的用户决定他们希望如何调用它。
如果有人希望在一个新的goroutine中并发运行它,那么wg可以在my_func()的 * 外部 * 进行处理,如下所示:

wg.Add(1)
go func() {
    defer wg.Done()
    my_func()
}()

这还提供了在wg.Done()调用之前执行的函数调用之前/之后放置进一步代码的可能性:

wg.Add(1)
go func() {
    defer wg.Done()

    // other code before
    my_func()
    // other code after
}()

还要注意的是,如果你在很多地方都有这个功能,你可以创建一个helper函数来负责goroutine的启动和等待组的处理:

func launchMyFunc(wg *sync.WaitGroup) {
    go func() {
        defer wg.Done()

        my_func()
    }()
}

您还可以创建一个接受任意无参数无返回函数的帮助器:

func launchFunc(wg *sync.WaitGroup, f func()) {
    go func() {
        defer wg.Done()

        f()
    }()
}

使用上面的帮助器,您可以这样做:

wg.Add(1)
launchMyFunc(wg)

// or
wg.Add(1)
launchFunc(wg, my_func)

相关问题