Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is go's preferred way to synchronize goroutines

I have an expensive function that I apply on all items of a slice. I'm using goroutines to deal with that, each goroutine dealing with one item of the slice.

func Huge(lst []foo) {
  for _, item := range lst {
     go performSlow(item)
  }

  // How do I synchronize here ?
  return someValue(lst)
}

The question is, as shown in the comment, what is the preferred way to wait all goroutines have done their job before calling the someValue function ? Passing on a channel to performSlow and waiting until everyone has written on it works, but it seems overkill :

func Huge(lst []foo) {
  ch := make(chan bool)

  for _, item := range lst {
     go performSlow(item, ch)  // performSlow does its job, then writes a dummy value to ch
  }

  for i := range lst {
     _ = <-ch
  }

  return someValue(lst)
}

Is there a better (i.e. more efficient and/or more idiomatic) way to do it ?

like image 953
Fabien Avatar asked Nov 18 '13 18:11

Fabien


People also ask

Are a way to synchronize the access of shared resources between Goroutines?

Another way to synchronize access to a shared resource is by using a mutex . A mutex is named after the concept of mutual exclusion. A mutex is used to create a critical section around code that ensures only one goroutine at a time can execute that code section.

How do you wait for Goroutines to finish?

In order to be able to run the goroutines until the finish, we can either make use of a channel that will act as a blocker or we can use waitGroups that Go's sync package provides us with.

What are Goroutines and how do they work?

A goroutine is a lightweight execution thread in the Go programming language and a function that executes concurrently with the rest of the program. Goroutines are incredibly cheap when compared to traditional threads as the overhead of creating a goroutine is very low.


1 Answers

Use sync.WaitGroup (http://godoc.org/sync#WaitGroup)

func Huge(lst []foo) {
  var wg sync.WaitGroup
  for _, item := range lst {
     wg.Add(1)
     go func() {
         performSlow(item)
         wg.Done()
     }()
  }

  wg.Wait()
  return someValue(lst)
}
like image 108
andybalholm Avatar answered Nov 22 '22 23:11

andybalholm