exit program when all goroutines finish

Issue

I have two go routine functions, one creates data and one adds the data to the database. When I’m done creating data I want to finish adding data but I don’t know how many times I’m going to call the function.

for {
  select {
  case c <- dataChan:
    go func() {
      if data == false {
        return // keeps the program running but never exits
      }
      createData(c.Data) // sends data to dataChan until data == false 
    }
    go func() {
      addData(c.Data) // need to keep the program running until all these goroutines finish
    }
  }
}

createData() creates and sends data to the dataChan and based on some variables it will eventually set data to false and cause the program to be held open by returning over and over again and stops creating more data, but I feel like there should be a cleaner way that allows me to exit when all the addData() goroutines finish. I have seen people use a channel for this but I don’t know exactly how many times I’m going to call the function.

UPDATE: WORKING CODE

var wg sync.WaitGroup
for {
  select {
  case c <- dataChan:
    wg.Add(1)
    go func() {
      if data == false {
        wg.Wait()
        os.Exit(0)
      }
      createData(c.Data)
    }
    go func() {
      addData(c.Data)
      defer wg.Done()
    }
  }
}

Solution

sync.WaitGroup is what you want here. You wg.Add(1) before starting each goroutine (or wg.Add(n) if you know the count up front), wg.Done() in each routine when finished, and wg.Wait() in main to wait untill all finish. The linked docs have an example, and as the docs note, copying it won’t do what you want; you may want to make the variable a pointer (wg := new(sync.WaitGroup)).

Answered By – twotwotwo

Answer Checked By – Mary Flores (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.