-2

Below is the scenario:

inputCh := g(abc) // return <- chan []string


slice := make([]map[string][]string, 0)
m := sync.Mutex{}
for whatever := range inputCh {
    go func(whatever []string) {
        matches := f(xyz, whatever) // returns map[string][]string
        m.Lock()
        slice = append(slice, matches)
        m.Unlock()
    }(whatever)
}

z := merge(slice...)

where we do no know, when inputCh gets closed(close(inputCh))

We need to invoke merge(slice...) only after all go-routines gets completed and updated slice


Not sure, if sync.WaitGroup can be used.

How to ensure merge(slice...) gets invoked only after slice gets updated by all go-routines?

overexchange
  • 15,768
  • 30
  • 152
  • 347

2 Answers2

1

Use sync.WaitGroup and check when channel was closed

var wg sync.WaitGroup

for {
    whatever, ok := <-inputCh
    if !ok { // check inputCh is close
        break
    }
    // add delta
    wg.Add(1)
    go func(whatever []string) {
        matches := f(xyz, whatever)
        m.Lock()
        slice = append(slice, matches)
        m.Unlock()
        // goroutine is done
        wg.Done()
    }(whatever)
}

// waits until all the goroutines call "wg.Done()"
wg.Wait()
kozmo
  • 4,024
  • 3
  • 30
  • 48
-3

You can use sync.WaitGroup.

// create a work group
var wg sync.WaitGroup
// add delta
wg.Add(len(inputCh))

slice := make([]map[string][]string, 0)
m := sync.Mutex{}
for whatever := range inputCh {
    go func(whatever []string) {
        matches := f(xyz, whatever) // returns map[string][]string
        m.Lock()
        slice = append(slice, matches)
        m.Unlock()
        // signal work group that the routine is done
        wg.Done()
    }(whatever)
}
// waits until all the go routines call wg.Done()
wg.Wait()