- author: CodeDonor
Understanding Go Routines: Concurrency vs. Parallelism
In the last section, we introduced the concept of launching a new Go routine in our program using the
go keyword. This creates a new Go routine and allows for concurrent execution. However, there's more to Go routines than just spawning them.
What Happens Behind the Scenes in Go Routines?
When we launch multiple Go routines in our program, the Go scheduler comes into play. It works with one CPU on our local machine and, by default, tries to use only one CPU, even if you're running on a dual-core machine.
This means that even though we launch multiple Go routines, only one is executed or running at any given time. The purpose of the Go scheduler is to monitor the code running inside each of these Go routines and decide which one to execute at a given time. It detects when one routine has finished running all of the code inside it or when a function has made a blocking call. It then pauses that routine and starts executing the next one.
When we have only one CPU, the execution changes back and forth between Go routines in a flash. The scheduler is responsible for cycling through them almost instantaneously.
However, this discussion about running one Go routine at a time only applies when we have one CPU. When we have multiple CPU cores, each can run a single Go routine at a time. As soon as we have multiple CPU cores, we can run multiple chunks of code at the same time.
Concurrency vs. Parallelism
Concurrency and parallelism are two terms that we encounter when talking about Go routines. Concurrency is when work can occur independently of each other. We can schedule work to be done throughout each other without waiting for one Go routine to finish before executing the next one.
On the other hand, parallelism refers to the ability to do multiple things at the same nanosecond. With parallelism, we can run multiple Go routines simultaneously on different CPU cores.
The difference between these two is that concurrency allows us to schedule work and switch between them on the fly. Parallelism allows us to execute multiple things simultaneously.
Child Go Routines
When we run a program, we always get one default Go routine created for us, which is referred to as the main routine. It's the one that starts to run all the code inside our main.go file.
Every other Go routine we create is a child Go routine, created using the
go keyword. Child Go routines don't get the same level of respect as the main routine. Therefore, we need to draw an actual line in the sand between the main routine and the child routines.
It's essential to understand this difference because, as soon as we start adding Go routines to our code, we might encounter a bug almost instantly. In the next section, we'll look at how to start adding support for Go routines to our program and solve these issues.
Understanding Go routines is key to building concurrent programs that can execute multiple tasks at the same time. By leveraging the Go scheduler and multiple CPU cores, we can create high-performance programs that offer better responsiveness and scalability.
The difference between concurrency and parallelism may seem subtle, but it's a crucial concept when it comes to Go routines. Likewise, understanding the difference between the main routine and child routines is essential to avoiding bugs in our code.