Golang execute several go routine in loop and then wait I'm new in Go and excited with its easy-to-use concurrency implementation. However I'm not sure if I'm doing it right in Golang way.
Consider the code where I spawn process(i int, ch chan int) every loop as separate goroutine. Then the result which comes from the channel will be consumed by consume(ch chan int, wg *sync.WaitGroup).
I know that the channel is blocking, so let's implement buffered channel. And of course I don't want the process terminated before every goroutine finished the operation, so I add WaitGroup.

func main() {
    var wg sync.WaitGroup
    n := 5
    ch := make(chan int, n)
    for i := 0; i &lt; n; i++ {
        println("Processing ", i)
        go process(i, ch)
        go consume(ch, &amp;wg)
    }
    println("Finished the process")
    wg.Wait()
}

func consume(ch chan int, wg *sync.WaitGroup) {
    wg.Add(1)
    defer wg.Done()
    println("Result ", &lt;-ch)
}

func process(i int, ch chan int) {
    ch &lt;- (i * 5)
}


Am I doing it right? Or there are better way to do this?
Many thanks!
Every time you execute a go statement it is passed to the scheduler. What if scheduling is delayed? wg.Add(1) is not executed and wg.Wait() is true. For example, run your code in the Go Playground where GOMAXPROCS is 1.

package main

import (
    "sync"
)

func main() {
    var wg sync.WaitGroup
    n := 5
    ch := make(chan int, n)
    for i := 0; i &lt; n; i++ {
        println("Processing ", i)
        go process(i, ch)
        go consume(ch, &amp;wg)
    }
    println("Finished the process")
    wg.Wait()
}

func consume(ch chan int, wg *sync.WaitGroup) {
    wg.Add(1)
    defer wg.Done()
    println("Result ", &lt;-ch)
}

func process(i int, ch chan int) {
    ch &lt;- (i * 5)
}


Playground: https://play.golang.org/p/dQ_lFRz2Y8a

Output:

Processing  0
Processing  1
Processing  2
Processing  3
Processing  4
Finished the process




Make sure that all the wg.Adds are run before wg.Wait. Move the println("Finished the process") to the correct place after the wg.Wait. For example,

waiting.go:

package main

import (
    "runtime"
    "sync"
)

func main() {
    println("GOMAXPROCS", runtime.GOMAXPROCS(0))
    var wg sync.WaitGroup
    n := 5
    ch := make(chan int, n)
    for i := 0; i &lt; n; i++ {
        println("Processing ", i)
        go process(i, ch)
        wg.Add(1)
        go consume(ch, &amp;wg)
    }
    wg.Wait()
    println("Finished the process")
}

func consume(ch chan int, wg *sync.WaitGroup) {
    defer wg.Done()
    println("Result ", &lt;-ch)
}

func process(i int, ch chan int) {
    ch &lt;- (i * 5)
}


Playground: https://play.golang.org/p/3czBixAjxdT

Output:

GOMAXPROCS 1
Processing  0
Processing  1
Processing  2
Processing  3
Processing  4
Result  0
Result  5
Result  10
Result  15
Result  20
Finished the process


Run the Go data race detector to check for data races. It finds none.

$ go run -race waiting.go
GOMAXPROCS 4
Processing  0
Processing  1
Result  0
Processing  2
Result  5
Processing  3
Result  10
Processing  4
Result  15
Result  20
Finished the process
$