简体   繁体   English

如何将 WaitGroup 传递给连续的 function 调用?

[英]How to pass WaitGroup to a sequential function call?

I have a function which can be called sequentially or concurrently in separate goroutine.我有一个 function 可以在单独的 goroutine 中顺序或同时调用。

I want to ensure that function is executed completely before main goroutine finishes, so I am passing *sync.WaitGroup argument to the function. Now, at some places the function is to be called sequentially.我想确保 function 在主 goroutine 完成之前完全执行,所以我将 *sync.WaitGroup 参数传递给 function。现在,在某些地方 function 将被顺序调用。

I can pass nil waitGroup to the function like this:我可以像这样将 nil waitGroup 传递给 function:

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

Is there any better way to achieve this?有没有更好的方法来实现这一目标?

Your my_func() should not know / should not care how it is executed (whether in a new goroutine or not).你的my_func()不应该知道/不应该关心它是如何执行的(无论是否在新的 goroutine 中)。 So just for this you should not pass wg .因此,仅此而已,您不应该通过wg Do not enforce concurrent or non-concurrent use of your API, let users of your package decide how they wish to call it.不要强制同时或非并发使用您的 API,让您的 package 的用户决定他们希望如何调用它。

If someone wishes to run it concurrently, in a new goroutine, wg can be handled outside of my_func() like this:如果有人希望同时运行它,在一个新的 goroutine 中, wg可以在my_func()之外处理,如下所示:

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

This also gives possibility to put further code before / after the function call that will be executed before the wg.Done() call:这也提供了在wg.Done()调用之前执行的 function 调用之前/之后放置更多代码的可能性:

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

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

Also note that if you have this in many places, you can create a helper function that takes care of the goroutine launching and waitgroup handling:还要注意,如果你在很多地方都有这个,你可以创建一个 helper function 来处理 goroutine 启动和等待组处理:

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

        my_func()
    }()
}

You can also create a helper that accepts an arbitrary no-arg no-return function:您还可以创建一个接受任意无参数不返回 function 的助手:

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

        f()
    }()
}

Using the above helpers this is how you could do the same:使用上面的助手,你可以这样做:

wg.Add(1)
launchMyFunc(wg)

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM