Why does it print out of sync

I am learning Go. I am reading a book and the following code

// This sample program demonstrates how to create goroutines
package main

import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)

// wg is used to wait for the program to finish goroutines.
var wg sync.WaitGroup

func main() {
	// Add a count of two, one for each goroutine.
	wg.Add(2)
	fmt.Println("Start Goroutines")
	//launch a goroutine with label "A"
	go printCounts("A")
	//launch a goroutine with label "B"
	go printCounts("B")
	// Wait for the goroutines to finish.
	fmt.Println("Waiting To Finish")
	wg.Wait()
	fmt.Println("\nTerminating Program")
}
func printCounts(label string) {
	// Schedule the call to WaitGroup's Done to tell we are done.
	defer wg.Done()
	// Randomly wait
	for count := 1; count <= 10; count++ {
		sleep := rand.Int63n(1000)
		time.Sleep(time.Duration(sleep) * time.Millisecond)
		fmt.Printf("Count: %d from %s\n", count, label)
	}
}

Produces the following results:
Start Goroutines
Waiting To Finish
Count: 1 from A
Count: 1 from B
Count: 2 from B
Count: 2 from A
Count: 3 from B
Count: 3 from A
Count: 4 from A
Count: 5 from A
Count: 4 from B
Count: 6 from A
Count: 5 from B
Count: 7 from A
Count: 6 from B
Count: 7 from B
Count: 8 from A
Count: 8 from B
Count: 9 from B
Count: 9 from A
Count: 10 from A
Count: 10 from B

Terminating Program

My question is why from count 4 is it out of sync and does it not print like 1 and 2 and 3 consecutively? Because from 8 again it print them in order

It depends on the go scheduler how to schedule individual goroutine. sync.WaitGroup only assures to finish a collection of goroutine.
wait() is just a blocking call until the waitgroup counter becomes zero.

1 Like

But it is the same every time so why does the go scheduler skip one after 3 and then back to normal at 8?

Because you are generating the same random pause intervals each time:

Top-level functions, such as Float64 and Int, use a default shared Source that produces a deterministic sequence of values each time a program is run.

You need to use a different seed each time. The scheduler is not involved in how the sequence is created, its only because of your “random” pause length.

1 Like

Thank you

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.