Concurrency in Golang

Learn via video courses
Topics Covered

Overview

Concurrency describes a process that occurs at the same time as other activities. It is a program's ability to do multiple things at the same time. Unlike other programming languages like Java and Python which used threads, Golang uses Goroutines. In This article, we will learn about Concurrency in Golang.

Why Use Concurrency?

Concurrency is a program's ability to run multiple functions at the same time. This means that the functions run individually without getting affected by others.

Concurrency is very important in modern software, As this promotes writing codes that can run simultaneously with other pieces of code without disturbing the overall flow of the program. Below are a few points explaining why we should use Concurrency in our application.

  • Better Performance
  • Improvement in execution time 
  • Better resources management
  • Taking full use of modern multicore processors.

What is Concurrency in Go?

Concurrency is when two or more function runs simultaneously and are independent of each other. A goroutine is a function that is capable of running concurrently with other functions in Golang. Goroutines are managed by Go-runtime. The Golang runtime scheduler has a feature to manage all the goroutines that are created and need processor time. The Golang scheduler binds the operating system's threads to execute the goroutines.

Programming languages such as Java and Python implement concurrency by using operating systems threads. Goroutines are cheap, lightweight threads.

concurrent-operations

Goroutines

Golang achieves concurrency by means of Goroutines. It's a special inbuilt feature in Golang which helps run two or more methods independently and simultaneously in connection with any other Goroutines present in your program. Every concurrent process in a Golang application can be called a Goroutine.

Goroutines are lightweight threads managed by Go-runtime. The cost of creating Goroutines is very small compared to the creation of an operating system thread. Every Golang Application has at least one Goroutine and that Goroutine is known as the main Goroutine. All the Goroutines are working under the main Goroutines if the main Goroutine is terminated, then all the Goroutines present in the program are also terminated.

Popular programming languages like Python and Java use thread pools to execute concurrency whereas Go has built-in features like Goroutines and Channels to achieve Concurrency. Goroutines are much easier to manage than thread pools that are purely operated by the operating system. This makes Golang a better way to implement concurrency.

Concurrency Basics

There are two important Concurrency Golang Concepts 

  • Goroutines : Goroutine is a function that runs simultaneously with other functions. 

  • Channels : A channel is a highway used for sending and receiving data between Goroutines. Channels provide a way for one goroutine to send structured data to another.

Concurrency vs Parallelism

concurrency-vs-parallelism

Concurrency - Concurrency is when the program is dealing with a number of tasks at once. This means the program is trying to manage tasks in a given period of time. But in Concurrency there will be only one task in execution, Not all tasks will run at the same time. Once a running task ends or comes into the waiting stage, a New task will be taken up and executed. This improves our application execution speeds as compared to traditional single-thread applications.

Parallelism - Parallelism is when the program is executing a number of tasks at the same time. That means if we have n tasks they will be continuously working without any breaks in between them. these make the execution of our programs fast but resource usage is generally high.

GoRoutines in Golang

You can create your own Goroutine simply by using the go keyword as a prefixing to the function or method call as shown in the below syntax:

Syntax:

How Goroutines Work?

Goroutines allow our application to become asynchronous in nature. Goroutines are different from threads and are managed by Go runtime.

When there is more than one Goroutine running in a Golang application, These Goroutines are propagated to the Go runtime scheduler which manages the lifecycle and allocates the Goroutine with an OS thread and memory.

When a Goroutine blocks the Go scheduler it performs a context-switch. It is the process of storing the state of the Goroutine so that it can be restored and execution can start at a later point. So while one goroutine is stored in the background the Go scheduler gives the thread to another goroutine for execution.

goroutines-working

Using Goroutines for Concurrent Processing

Below is example of Goroutines in Golang.

output:

goroutines example

Locking and Waiting

Anytime two or more Goroutines are dealing with the same data, and that data changes frequently, it can cause a condition called "racing". The problem arises when two Goroutine tries to update the value of shared resource at the same time. This can create unwanted scenarios. To avoid such problems we use locking with the help of Mutex. A Mutex is a method used as a locking mechanism to ensure that only one Goroutine is accessing the critical section of code at a given point in time.

In Golang if the execution of the main Goroutine is completed all the other Goroutines in the programs are also stopped at the same time. To Avoid this scenario we can use waiting with the help of a Waitgroup. A WaitGroup is actually a type of counter which blocks the execution of Goroutines, until its internal counter becomes 0.

Below is an example showing the use of Mutex and Waitgroup where we try to manipulate a common parameter and print it.

output:

Example of Locking and Waiting

Conclusion

  • We learned a whole lot about Concurrency in Golang.
  • We explored what is the difference between Concurrency and Parallelism.
  • We implemented a few examples with Golang Concurrency.