Introduction to Concurrency in Golang

Sonu Kumar Saw
·Feb 12, 2022·

4 min read

Introduction to Concurrency in Golang

Subscribe to our newsletter and never miss any upcoming articles

In computer science, often we write programs written as a linear path of code, for example, a program to read a JSON file or a program to calculate your bill. This type of program to one task at a time and follow a linear path to perform that task and finish. But sometimes we need to write a program that needs to execute multiple paths, in such conditions we use concurrent programming. For example, A web service has to connect multiple requests, process the data, and then respond to the requests. Since web services are built to handle concurrent requests, we don't have to wait for one request to complete and return the response in order to send another request to the web service.

Concurrency vs Parallelism

Programmers generally get confused by the word Concurrency with Parallelism, both the topics are related but not the same. Concurrency is the composition of independently executing processes, while Parallelism is the simultaneous execution of the programs.

Below diagram shows how Concurrency is different from Parallelism

Group 3 (7).png

The flow diagram on the left shows, the same processor is being used to complete two different tasks concurrently. The flow diagram on the right shows two processes being executed parallelly in two different processors. You can learn more about this from the workshop by Rob Pike.

Concurrency in Go

Concurrency in Go has been built directly into Go's runtime. Also, Go has a built-in library which makes writing and maintaining concurrent go programs easier as compared to the other programming languages.

Goroutines

Concurrency in Go is powered by goroutines. Goroutines aren't OS threads, they are higher levels of abstraction known as coroutines. They are managed by the Go's runtime. Every Go program has at least one goroutine by default, which is created by the main function.

To create a goroutine we use the keyword go in front of any function. Here's a simple example of a goroutine.

package main

import "fmt"

func sayGreetings() {
    fmt.Println("Hello World!!")
}

func main() {
    go sayGreetings()
}

So, let's discuss what is happening in the code shared above. We have created a function names sayGreetings, which will be printing a message "Hello World". We have another function, main, which is calling the sayGreetings function as a goroutine. When we run this program, It will create two goroutines. The first one would be the main goroutine, and another one would be the goroutine created by the sayGreetings function.

This program will compile successfully, however, there is a problem with this example: it's undetermined whether Hello World!! will be printed on the console or not. The goroutine for sayGreetings will be created, but, we can't determine if it will be executed by the time the main goroutine executes completed and exits.

So, In order to solve the above issue, we have to make sure that the sayGreetings goroutine gets executed before the main goroutine completes its execution. We can make use of the time package and put our main goroutine on sleep for 2 secs.

package main

import (
    "fmt"
    "time"
)

func sayGreetings() {
    fmt.Println("Hello World!!")
}

func main() {
    go sayGreetings()
    time.Sleep(2 * time.Second)
}

If we run the above program, we will get the expected output i.e, Hello World!! in the console.

Even though we were able to print Hello World!! in the console, the above code is not correct. By adding time.Sleep() we are just increasing the probability of the main goroutine not completing its execution before sayGreetings. If we add another goroutine in our program which takes more than 2 seconds to complete its execution, then again we will get into the same issue as before. To make sure that our code works deterministically we need to use Go's synchronization primitives such as Mutex locks, waitgroups, channels, etc.

We will explore more about Go's synchronization primitives in our next part of this series.

Before You Leave

If you found this article valuable, you can support us by dropping a like and sharing this article with your friends.

You can sign up for our newsletter to get notified whenever we post awesome content on Golang.

Frame 1.png

Did you find this article valuable?

Support ioScript.org by becoming a sponsor. Any amount is appreciated!

See recent sponsors Learn more about Hashnode Sponsors
 
Share this