should I pass functions as parameter of a go routine?

624 views
Skip to first unread message

Julien Pivotto

unread,
Mar 4, 2021, 11:01:20 AM3/4/21
to golang-nuts
Hello,

In the following example: https://play.golang.org/p/yz_ifHC-Hut

for _, onedoer := range d {
  go onedoer.do(&wg)
}

Should I pass the function onedoer.do as a parameter of the go routine:  https://play.golang.org/p/WHPahoayDbM ?

for _, onedoer := range d {
  go func(od *doer, w *sync.WaitGroup) {
    od.do(w)
  }(onedoer, &wg)
}

I am wondering if `go func()` could return before figuring out which function to run, creating a race with the loop.


Thanks in advance!

Axel Wagner

unread,
Mar 4, 2021, 11:11:40 AM3/4/21
to Julien Pivotto, golang-nuts
Interesting question. I think the code is fine. From the spec:

> The function value and parameters are evaluated as usual in the calling goroutine, but unlike with a regular call, program execution does not wait for the invoked function to complete.

This means `onedoer.do` is immediately evaluated, before the loop continues. The usual issue with loops is due to closures. So, this would be wrong and have exactly the issue you are worried about:

for _, onedoer := range d {
    go func() { oneoder(&wg) }
}

But the go statement isn't equivalent to that, it doesn't close over the function value, it evaluates it.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/6547c92f-a009-4fd4-abb2-801b2c44ea67n%40googlegroups.com.

Julien Pivotto

unread,
Mar 4, 2021, 11:50:19 AM3/4/21
to golang-nuts
Thank you for your quick answer, it is of a great help.

have a nice day.

Max Renaud

unread,
Mar 6, 2021, 9:45:53 PM3/6/21
to golang-nuts
In your second example, the address of wg doesn't change with each iteration so you can use:
for _, onedoer := range d {
go func(od *doer) {
od.do(&wg)
}(onedoer)
}


Reply all
Reply to author
Forward
0 new messages