Tales of a Software Craftsman

Goroutines: Threading made easy!

This post is dedicated to the awesome concept of “Goroutines” in Go. A “Goroutine” (Go Routine?) is a lightweight thread implementation that executes asynchronously with the main process. To define a goroutine, we use the “go” keyword before a function call. Instead of a regular blocking call, the function is then executed asynchronously.

Let’s jump into a quick demonstration. We shall write a program that creates multiple threads, each thread sleeping for a random period of time. For us, the mere mortals, we shall politely ask the threads to print some information so that we can tell when they go to sleep and when they wake up!

Go

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

packagemain

import(

"fmt"

"math/rand"

"time"

)

funcmain(){

// let's create 5 goroutines using for loop

fori:=0;i<5;i++{

// the go keyword makes it a goroutine, making the function

// execute asynchronously instead of a blocking call

// we are using anonymous function for simple

// demonstration

gofunc(num int){

// let's seed the random number generator

rand.Seed(time.Now().UnixNano())

// create a random number for sleeping

sleepDuration:=rand.Intn(20)

// let's print a message before sleeping

fmt.Printf("[%d]: Sleeping for %d milisecs \n",num,sleepDuration)

// ZzzzZzzZZZzzzz!!

time.Sleep(time.Duration(sleepDuration)*time.Millisecond)

// Good morning, World!

fmt.Printf("[%d]: Woke up! \n",num)

}(i)

}

// delay the main process so that others can print to the terminal

varinput string

fmt.Scanln(&input)

}

The blocking call (from the main process) always executes first. The Scanln() call waits for user input thus allowing the async functions to print their information on the terminal. If we don’t wait, the main process will finish execution and the program will quit. Since the other functions are async, we shall never see their outputs. So we wait and wait for their messages! 🙂

Sample output?

1

2

3

4

5

6

7

8

9

10

11

12

Lighthouse:~/Codes/go

$go run main.go

[0]:Sleeping for3milisecs

[1]:Sleeping for18milisecs

[2]:Sleeping for2milisecs

[3]:Sleeping for16milisecs

[4]:Sleeping for9milisecs

[2]:Woke up!

[0]:Woke up!

[4]:Woke up!

[3]:Woke up!

[1]:Woke up!

It’s simple, right? In some languages, you have to subclass a built in class and then define specific methods to direct the behavior/actions. In Go, you just define a function and prepend “go” before making the function call. Good thing, you can use anonymous functions and invoke them immediately as well.

For communication between these goroutines, we can use “Channels”. Hope to write another blog post on using channels soon.