@tjameson did a great job explaining how to use WaitGroup , how to pass a reference to your WaitGroup object to your function. The only change I would make with his example is the defer lever when you are Done . I think this defer ws.Done() should be the first statement in your function.
I like WaitGroup simplicity. However, I do not like that we need to pass a link to goroutine, because this will mean that the concurrency logic will be mixed with your business logic.
So, I came up with this general function to solve this problem for me:
// Parallelize parallelizes the function calls func Parallelize(functions ...func()) { var waitGroup sync.WaitGroup waitGroup.Add(len(functions)) defer waitGroup.Wait() for _, function := range functions { go func(copy func()) { defer waitGroup.Done() copy() }(function) } }
So your example can be solved as follows:
type Object struct { //data } func (obj *Object) Update() { //update data time.Sleep(time.Second) fmt.Println("Update done") return } func main() { functions := []func(){} list := make([]Object, 5) for _, object := range list { function := func(obj Object){ object.Update() }(object) functions = append(functions, function) } Parallelize(functions...) fmt.Println("Group done") }
If you want to use it, you can find it here https://github.com/shomali11/util
Raed shomali
source share