Go - Concurrency and Parallelism
Last Updated :
05 Feb, 2025
Concurrency and parallelism are key to improving application performance. Go, with its efficient concurrency model, allows developers to create scalable, high-performance applications.
1. Concurrency
Concurrency refers to the ability of a program to make progress on multiple tasks simultaneously, but not necessarily in parallel. Concurrency involves managing multiple tasks that are being executed in an overlapping manner, often on a single CPU core. In essence, concurrency allows a program to handle multiple tasks at the same time by switching between them, making the program appear as if it’s running multiple tasks concurrently.
How Concurrency Works in Go?
Go handles concurrency using Goroutines, which are lightweight threads managed by the Go runtime. Goroutines are multiplexed onto a smaller number of operating system threads, allowing Go to manage many tasks concurrently without the overhead of creating a separate thread for each task.
The Go scheduler plays a key role in concurrency by determining which Goroutine should run at any given time. The scheduler manages task-switching between Goroutines, ensuring that the CPU resources are efficiently utilized.
Example:
func task(id int) {
fmt.Printf("Task %d is starting\n", id)
time.Sleep(2 * time.Second)
fmt.Printf("Task %d is completed\n", id)
}
func main() {
go task(1)
go task(2)
time.Sleep(3 * time.Second) // Waiting for both tasks to complete
fmt.Println("All tasks completed concurrently!")
}
In this example, two tasks run concurrently. Although they don’t run simultaneously (because there’s only one CPU core in this case), they’re executed in an overlapping manner, giving the appearance of concurrency.
2. Parallelism
Parallelism in computing refers to the execution of multiple tasks simultaneously, typically across multiple processors or CPU cores. Unlike concurrency, where tasks are handled in an overlapping manner, parallelism allows tasks to be executed literally at the same time, each on a separate processing unit.
How Parallelism Works in Go?
In Go, parallelism is achieved by running multiple Goroutines on different processors or CPU cores. Go's runtime system, coupled with the Go scheduler, distributes Goroutines efficiently across the available cores, enabling true parallel execution.
For instance, a task that requires intensive computation, such as processing large datasets or performing complex calculations, can benefit from parallel execution by breaking down the work into smaller tasks that are run simultaneously on multiple CPU cores. Go's ability to handle parallelism effortlessly makes it an ideal choice for high-performance applications, such as data analytics, real-time processing, and scientific computing.
Example:
func main() {
var wg sync.WaitGroup
cores := 4
// Creating 4 Goroutines to simulate parallelism
for i := 0; i < cores; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
fmt.Printf("Running task on Goroutine %d\n", id)
}(i)
}
wg.Wait() // Wait for all Goroutines to complete
fmt.Println("All tasks completed in parallel!")
}
In this example, Go schedules four Goroutines to run simultaneously, each performing a task on a separate CPU core.
Concurrency vs Parallelism in Golang
Aspect | Concurrency | Parallelism |
---|
Definition | Multiple tasks making progress at the same time, not necessarily simultaneously. | Tasks executed simultaneously on separate processors or cores. |
Execution Model | Tasks share CPU time and resources. | Tasks run on multiple CPU cores, utilizing true parallel execution. |
Focus | Managing multiple tasks efficiently. | Executing tasks at the same time. |
Go Mechanism | Managed using Goroutines. | Achieved using multiple CPU cores, assisted by the Go scheduler. |
Concurrency and Parallelism
Go (Golang) is designed for concurrency, making it easy to write concurrent applications. It uses goroutines, lightweight functions that run concurrently, and channels, which allow communication and synchronization between goroutines.
- Goroutines: Efficient, independently scheduled tasks managed by Go's runtime.
- Channels: A way for goroutines to communicate and coordinate.
Go also supports parallelism by utilizing multiple CPU cores, distributing goroutines across them for better performance. Go simplifies both concurrency with goroutines and channels, and parallelism using multi-core processing, making it efficient for scalable applications.
Similar Reads
Goroutines - Concurrency in Golang Goroutines in Go let functions run concurrently, using less memory than traditional threads. Every Go program starts with a main Goroutine, and if it exits, all others stop.Examplepackage mainimport "fmt"func display(str string) { for i := 0; i < 3; i++ { fmt.Println(str) }}func main() { go displ
2 min read
Difference Between Golang and Rust the Golang It is an open-source programming language that is statically-typed and compiled language. Go language has been developed by Robert Griesemer, Rob Pike, and Ken Thompson at Google. It was introduced back in 2007 by Google and first launched in 2009. It supports concurrency which provides h
3 min read
Go - Defer, Panic, and Recover Error handling is crucial for writing robust and maintainable code in Go. It provides three key tools:defer: Delays function execution until the surrounding function completes.panic: Immediately stops the program when a critical error occurs.recover: Regains control after a panic to prevent a crash.
5 min read
Atomic Variable in Golang In Go language, Atomic Variables are utilized in order to control state. Here, the "sync/atomic" package must be used to use these variables. Moreover, it also prevents race conditions which allows two or more Goroutines to access identical sources. The Atomic counters are available for several goro
3 min read
Difference Between Golang and Ruby Before stepping into a new project software developing team goes through severe discussions in order to choose the best language for their project. As we are aware that different technologies have their pros and cons and similarly the technology which is looking vibrant for one project might be lack
4 min read
Go - Non Blocking Channel Operations A non-blocking channel operation is a channel operation (either sending or receiving) that does not block the goroutine executing it. Instead of waiting for the operation to succeed, the goroutine proceeds to the next line of code immediately. This is particularly useful in scenarios where you donât
5 min read