# goroutines order of execution

## Issue

I’m trying to understand this piece of code, not sure why the 2nd go is executed before the 1st one. It’d be great if someone can really help me out with this!

``````func sum(a []int, c chan int) {
fmt.Println("summing: ", a)
total := 0
for _, v := range a {
total += v
}
//fmt.Println("send to c",total)
c <- total  // send total to c
}
func main() {
//a := []int{7, 2, 8,134,23,23,1,23,1234,143, -9, 4, 0, 1234}

c := make(chan int)

go sum([]int{1,2,3}, c)
go sum([]int{4,5,6}, c)

x := <-c
fmt.Println(x)
x = <-c
fmt.Println(x)
}
``````

OUTPUT:

``````summing:  [4 5 6]
15
summing:  [1 2 3]
6
``````

## Solution

You have nothing explicitly synchronizing the order of the two goroutines. If you run this enough times, you will see the calls to `fmt.Println` print in different sequences. When executing goroutines, as they are concurrent operations, you have no guarantees when they will execute and/or complete. You need to use various standard library packages, or channels themselves to synchronize the execution of concurrently running goroutines.

For example (by leveraging the blocking nature of channels, you could do something like):

``````func main() {

c := make(chan int)

go sum([]int{1, 2, 3}, c)

//use the channel to block until it receives a send
x := <-c
fmt.Println(x)

//then execute the next routine
go sum([]int{4, 5, 6}, c)

x = <-c
fmt.Println(x)
}
``````

Another example (significantly less practical, but here to look at other common go synchronization features) you could introduce a wait group, and a range over a channel:

``````func sum(a []int, c chan int, wg *sync.WaitGroup) {
defer wg.Done()
fmt.Println("summing: ", a)
total := 0
for _, v := range a {
total += v
}
//fmt.Println("send to c",total)
c <- total // send total to c
}

func main() {

c := make(chan int)
wg := new(sync.WaitGroup)

//concurrently call the concurrent calls to sum, allowing execution to continue to the range of the channel
go func() {
//increment the wait group, and pass it to the sum func to decrement it when it is complete
go sum([]int{1, 2, 3}, c, wg)
//wait for the above call to sum to complete
wg.Wait()
//and repeat...
go sum([]int{4, 5, 6}, c, wg)
wg.Wait()
//all calls are complete, close the channel to allow the program to exit cleanly
close(c)
}()

//range of the channel
for theSum := range c {
x := theSum
fmt.Println(x)
}

}
``````

Answered By – syllabix

Answer Checked By – David Goodson (GoLangFix Volunteer)