How to Use Goroutines in Go

Table of Contents

  1. Introduction
  2. Prerequisites
  3. Setting Up Go
  4. Goroutines 1. Creating Goroutines 2. Synchronizing Goroutines

  5. Conclusion

Introduction

In Go, goroutines are lightweight threads managed by the Go runtime. Goroutines enable concurrent programming, allowing tasks to be executed concurrently without the need for explicit thread management. This tutorial will cover the basics of using goroutines in Go, including how to create and synchronize them. By the end of this tutorial, you will have a solid understanding of how to leverage goroutines for concurrent programming in Go.

Prerequisites

Before starting this tutorial, you should have a basic understanding of Go syntax and have Go installed on your machine. If you haven’t already, you can download and install Go from the official Go website at golang.org.

Setting Up Go

To verify if Go is installed correctly, open a terminal or command prompt, and enter the following command:

go version

You should see the installed Go version printed on your screen. If not, please revisit the installation process and ensure that Go is properly installed.

Goroutines

Creating Goroutines

Goroutines are created by using the go keyword followed by a function call or an anonymous function. The go keyword launches the function as a goroutine, allowing it to run concurrently with the main program.

Let’s start by creating a simple example that demonstrates the creation of goroutines:

package main

import (
	"fmt"
	"time"
)

func printNumbers() {
	for i := 1; i <= 5; i++ {
		time.Sleep(1 * time.Second)
		fmt.Println(i)
	}
}

func main() {
	go printNumbers()
	fmt.Println("Main function")
	time.Sleep(5 * time.Second)
}

In the above example, we have a function printNumbers that repeatedly prints numbers from 1 to 5 with a delay of 1 second between each print statement. We launch this function as a goroutine using the go keyword in the main function. The main function also prints a message. We introduce a delay of 5 seconds using time.Sleep to allow the goroutine to finish execution before the program exits.

When you run the above code, you will see the numbers being printed concurrently along with the output of the main function.

Synchronizing Goroutines

In some cases, you may need to wait for goroutines to complete their execution before continuing with the main program. Go provides synchronization primitives like channels and wait groups to coordinate goroutines.

Let’s modify the previous example to wait for the goroutine to complete using a channel:

package main

import (
	"fmt"
	"time"
)

func printNumbers(ch chan bool) {
	for i := 1; i <= 5; i++ {
		time.Sleep(1 * time.Second)
		fmt.Println(i)
	}

	ch <- true // Signal completion to the channel
}

func main() {
	ch := make(chan bool)
	go printNumbers(ch)
	fmt.Println("Main function")
	<-ch // Wait for the goroutine to complete
}

In the updated example, we create a channel ch of type bool using make function. Inside the goroutine, after printing the numbers, we send true to the channel ch to indicate the completion of goroutine execution. In the main function, we wait for the completion of the goroutine by receiving a message from channel ch using <-ch syntax.

By synchronizing goroutines, we ensure that the main program waits for the goroutine to finish before exiting.

Conclusion

Goroutines are a powerful feature of Go that allow concurrent execution of tasks. In this tutorial, you learned how to create goroutines using the go keyword and how to synchronize them using channels. Armed with this knowledge, you can now leverage goroutines to write efficient and concurrent Go programs.

With practice and further exploration, you will discover more advanced techniques for using goroutines, such as using select statements, goroutine pools, and handling errors in goroutines. Keep experimenting and building on this foundation to become proficient in writing concurrent programs in Go.