Why does it print out of sync

(Calvin Cani) #1

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

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

import (

// 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.
	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")
	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

(Oshank Kumar) #2

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.

(Calvin Cani) #3

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

(Norbert Melzer) #4

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.

(Calvin Cani) #5

Thank you