Ordered Printing With Goroutines In Go

development golang

In today’s snippet, let’s look at how we can use synchronization techniques in Go to print natural numbers in order from two different goroutines. In our example here, we have two goroutines; one goroutine will print even numbers while the other goroutine will print odd numbers, but the output has to be in increasing order. To implement this, we will use a channel to synchronize the printing in the two goroutines. We will also use sync.WaitGroup to wait for the goroutines to finish before exiting the code. Note that we will need an unbuffered channel so that one goroutine is blocked while the other is printing the number. The even goroutine will use the done variable to indicate to the odd goroutine that it is done with the printing and there is nothing listening to the syncChannel. Without this, you will see a deadlock at the end of the printing.

There may be other ways to do this, but here is my implementation. If you have other ways to do this, please share it in the comments.


package main

import (
	"fmt"
	"sync"
	"sync/atomic"
)

func main() {
	var done int32
	syncChannel := make(chan bool) // unbuffered channel.

	wg := new(sync.WaitGroup)
	wg.Add(2)

	go func() {
		// prints even numbers.
		defer wg.Done()

		for i := 0; i < 50; i += 2 {
			<-syncChannel

			fmt.Printf("%d ", i)

			syncChannel <- true
		}
		atomic.StoreInt32(&done, 1)
	}()

	syncChannel <- true

	go func() {
		// prints odd numbers.
		defer wg.Done()

		for i := 1; i < 50; i += 2 {
			<-syncChannel

			fmt.Printf("%d ", i)

			if atomic.LoadInt32(&done) != 0 {
				return
			}

			syncChannel <- true
		}
	}()

	wg.Wait()
	close(syncChannel)
}

Get new posts by email

Comments

comments powered by Disqus