Sling Academy
Home/Golang/Concurrency vs Parallelism: What’s the Difference in Go?

Concurrency vs Parallelism: What’s the Difference in Go?

Last updated: November 27, 2024

In modern programming, managing how multiple processes and tasks are handled is an important aspect of performance improvements. Two fundamental concepts often discussed in this context are concurrency and parallelism. While these terms are sometimes used interchangeably, they have distinct meanings and implications, especially when working with the Go programming language. In this article, we will delve into the differences between concurrency and parallelism, providing code examples to illustrate these concepts in Go.

Understanding Concurrency

Concurrency is about dealing with lots of things at once. In Go, concurrency is supported natively thanks to goroutines and channels. A goroutine is a lightweight thread of execution, making concurrent programming straightforward.

Here is a simple example of concurrency in Go using goroutines:

package main

import (
    "fmt"
    "time"
)

func sayHello() {
    for i := 0; i < 5; i++ {
        fmt.Println("Hello")
        time.Sleep(100 * time.Millisecond)
    }
}

func sayWorld() {
    for i := 0; i < 5; i++ {
        fmt.Println("World")
        time.Sleep(100 * time.Millisecond)
    }
}

func main() {
    go sayHello()
    go sayWorld()
    time.Sleep(1 * time.Second)
}

In this example, both sayHello() and sayWorld() are launched as goroutines and run concurrently. Notice how you use the go keyword to call the functions. Even though these functions are executed in order, they will interleave their output, showing concurrency.

Understanding Parallelism

Parallelism, on the other hand, is about doing multiple things at the same time. For this to occur, a multicore processor is required to handle threads actually running simultaneously. Parallelism can be tricky to achieve because it often requires careful management of shared resources.

Let’s modify our previous example to achieve parallelism:

package main

import (
    "fmt"
    "runtime"
    "time"
)

func sayHello() {
    for i := 0; i < 5; i++ {
        fmt.Println("Hello")
        time.Sleep(100 * time.Millisecond)
    }
}

func sayWorld() {
    for i := 0; i < 5; i++ {
        fmt.Println("World")
        time.Sleep(100 * time.Millisecond)
    }
}

func main() {
    // Set the number of OS threads to use
    runtime.GOMAXPROCS(2)
    go sayHello()
    go sayWorld()
    time.Sleep(1 * time.Second)
}

In this example, runtime.GOMAXPROCS(2) sets the number of operating system threads that our program can use, enabling the Go runtime to run the goroutines on two different CPU cores concurrently, achieving parallelism.

Conclusion

Understanding the difference between concurrency and parallelism will help you leverage the full potential of Go when optimizing your applications' performance. By using goroutines effectively and configuring them for multicore execution, you can dramatically improve your program’s capability to handle multiple tasks and processes efficiently.

Next Article: Deep Dive into Goroutine Lifecycle in Go

Previous Article: When to Use Goroutines vs Worker Pools in Go

Series: Concurrency and Synchronization in Go

Golang

Related Articles

You May Also Like

  • How to remove HTML tags in a string in Go
  • How to remove special characters in a string in Go
  • How to remove consecutive whitespace in a string in Go
  • How to count words and characters in a string in Go
  • Relative imports in Go: Tutorial & Examples
  • How to run Python code with Go
  • How to generate slug from title in Go
  • How to create an XML sitemap in Go
  • How to redirect in Go (301, 302, etc)
  • Using Go with MongoDB: CRUD example
  • Auto deploy Go apps with CI/ CD and GitHub Actions
  • Fixing Go error: method redeclared with different receiver type
  • Fixing Go error: copy argument must have slice type
  • Fixing Go error: attempted to use nil slice
  • Fixing Go error: assignment to constant variable
  • Fixing Go error: cannot compare X (type Y) with Z (type W)
  • Fixing Go error: method has pointer receiver, not called with pointer
  • Fixing Go error: assignment mismatch: X variables but Y values
  • Fixing Go error: array index must be non-negative integer constant