[英]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.