Why the lower go routine function runs first?

package main

import (
	"fmt"
	"sync"
	"time"
)

func odd(ch chan int, wg *sync.WaitGroup) {
	for i := 1; ; i += 2 {
		<-ch
		fmt.Println(i)
		time.Sleep(time.Second)
		ch <- 1
	}
	wg.Done()
}

func even(ch chan int, wg *sync.WaitGroup) {
	for i := 2; ; i += 2 {
		<-ch
		fmt.Println(i)
		time.Sleep(time.Second)
		ch <- 1
	}
	wg.Done()
}

func main() {
	ch := make(chan int)
	var wg sync.WaitGroup
	wg.Add(2)
	go even(ch, &wg)
	go odd(ch, &wg)
	ch <- 1
	wg.Wait()
}

I want to know why does the function named odd gets executed first then the function named even? Am I missing something very basic?

There is no deterministic order between both go routines.

The observed results may change depending on the version of go used to compile, the count of your CPU/cores, weather, randomness.

6 Likes

Right! weather :smiley:

1 Like

Look at this slightly modified version of your program. It has the advantage that this code runs then ends. I ran it on the go playground for 10 times, one out of those 10 times it printed first “even 2” otherwise it was “odd 2”.

The thing which decides what goroutine runs first, is how the 2 goroutines are scheduled at runtime. The first goroutine has a slight advantage over the second, as main first launches it then the second.

Once either of the two goroutine has started running, then because it writes on a channel while the other goroutine waits reading from that same channel, the order is fixed.

@NobbZ & @aceix stop bashing on OP please, his question is legitimate even if poorly worded.

I’m not bashing. I always use weather or solar flares as an exaggeration for non deterministic randomness far beyond our control. If this is perceived as “bashing” I’m sorry about that, this really wasn’t what I wanted to do.

2 Likes