0

I was experimenting with goroutines, and it seems I can't modify the value of a struct within a goroutine (example below). Is there any work around for this?

EDIT: It appears that the code runs if I place a sleep statement, indicating that the goroutines would run if given more time, but they finish running after everything in main() has already executed. How do I "wait" for my goroutines to finish before proceeding?

package main import ( "fmt" ) type num struct { val int } func (d *num) cube_val() { fmt.Println("changing value...") d.val = d.val*d.val*d.val } func main() { a := []num{num{1},num{3},num{2},num{5},num{4}} for i := range a { go a[i].cube_val() } // code that waits for go routines to finish should get inserted here ... fmt.Println(a) // change does NOT happen for i := range a { a[i].cube_val() } fmt.Println(a) // change happens, and fmt.Println statements worked? } 
1
  • I believe you'd have to block the go routine call because there's no guarantees the call has even been made or has completed. You can't guarantee that a has been changed, hence why causing it to sleep leads to the go routines completing. This may help you: stackoverflow.com/questions/19208725/… Commented Mar 11, 2017 at 13:02

1 Answer 1

5

The changes do happen. But they happened for you after the fmt.Println(a). In fact there are no guarantees on the execution order of the goroutines and the print statement, without synchronization.

If you want the fmt.Println(a) happen after the goroutines have completed, you have to wait for them, for example: (see also on Playground)

func main() { var wg sync.WaitGroup a := []num{num{1}, num{3}, num{2}, num{5}, num{4}} for i := range a { wg.Add(1) go func(d *num) { defer wg.Done() d.cube_val() }(&a[i]) } wg.Wait() fmt.Println(a) } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.