Customize Consent Preferences

We use cookies to help you navigate efficiently and perform certain functions. You will find detailed information about all cookies under each consent category below.

The cookies that are categorized as "Necessary" are stored on your browser as they are essential for enabling the basic functionalities of the site. ... 

Always Active

Necessary cookies are required to enable the basic features of this site, such as providing secure log-in or adjusting your consent preferences. These cookies do not store any personally identifiable data.

No cookies to display.

Functional cookies help perform certain functionalities like sharing the content of the website on social media platforms, collecting feedback, and other third-party features.

No cookies to display.

Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics such as the number of visitors, bounce rate, traffic source, etc.

No cookies to display.

Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.

No cookies to display.

Advertisement cookies are used to provide visitors with customized advertisements based on the pages you visited previously and to analyze the effectiveness of the ad campaigns.

No cookies to display.

Master Concurrency in Golang with Goroutines and Channels

Master Concurrency in Golang with Goroutines and Channels

Last updated on August 4th, 2023

Introduction

Concurrency in Golang: Concurrency is an important concept in programming that allows executing multiple tasks simultaneously. Golang is designed with concurrency in mind and provides built-in primitives like goroutines and channels that make writing concurrent programs easy.

Why Concurrency in Golang?

Golang’s concurrency mechanisms allow developers to efficiently utilize multi-core CPUs and improve performance without introducing threading complexity. Some key advantages of concurrency in Golang:

  • Simpler code: Goroutines are lighter than threads and managed by Golang runtime. No need to deal with locks, conditions etc.
  • Better resource utilization: Golang can leverage multiple cores by running goroutines concurrently.
  • Scalable by default: Goroutines handle work queuing and switching automatically.
  • No race conditions: Channels provide synchronization and messaging safely between goroutines.

Goroutines

A goroutine is a lightweight thread of execution in Golang. To start a goroutine, simply prefix go keyword to a function call.

go someFunction()

This will execute someFunction() concurrently in a new goroutine. The parent function continues execution as normal without blocking.

Goroutines are managed by Golang runtime and scheduled efficiently across OS threads. We don’t have to worry about creating/managing threads explicitly.

Example: Concurrent Network Calls

package main

import (
  "fmt"
  "net/http"
)

func fetch(url string) {
  res, err := http.Get(url)
  fmt.Println(url, res, err) 
}

func main() {
  urls := []string{
    "https://www.google.com",
    "https://www.facebook.com",
    "https://www.amazon.com",
  }

  for _, url := range urls {
    // Execute HTTP request concurrently 
    go fetch(url) 
  }

  // Wait for goroutines to finish
  fmt.Println("All fetches completed")
}

This performs concurrent HTTP requests using goroutines and fetches all URLs asynchronously.

Channels

Channels provide a safe way for goroutines to communicate and synchronize execution. They act as pipes between goroutines through which data can be sent & received.

ch := make(chan int)
  • ch <- val sends value val on channel ch
  • val := <-ch receives from ch and assigns to val

Channels block goroutines until the send/receive operation is complete. This prevents race conditions between goroutines accessing shared data.

Example: Worker Pools

package main

import "fmt"

func worker(tasks <-chan int, results chan<- int) {
  for task := range tasks {
    fmt.Println("Processing task", task)
    results <- task * 2
  }
}

func main() {
  
  tasks := make(chan int, 10)
  results := make(chan int, 10)

  // Start 3 worker goroutines
  for i := 0; i < 3; i++ {
    go worker(tasks, results)
  }

  // Send 5 tasks
  for i := 0; i < 5; i++ {
    tasks <- i
  }
  
  close(tasks)
  
  // Print results
  for i := 0; i < 5; i++ {
    res := <-results
    fmt.Println(res)
  }  
}

This starts 3 concurrent worker goroutines that process tasks from a shared task channel and send results on results channel.

Frequently Askes Questions

How do I make a Golang program concurrent?

You can achieve concurrency in Golang by using goroutines, which are lightweight threads managed by the Golang runtime. Start a goroutine by adding the go keyword before a function call. Use channels for communication between goroutines to synchronize data access and execution.

Does Golang support concurrency?

Yes, concurrency is a key feature built into Golang. The language provides high-level primitives like goroutines and channels that make it easy for developers to write concurrent programs and take advantage of multiple cores.

What is concurrency vs asynchronous in Golang?

Concurrency allows multiple things to execute independently in an overlapping time period. Asynchronous executes tasks out of sequence without blocking other operations. Goroutines enable concurrency while channels provide asynchronous communication in Golang.

Is goroutine parallel or concurrent?

Goroutines enable concurrency in Golang as they can run independently and simultaneously. But goroutines on a single thread are not parallel since the CPU core is shared. True parallelism using goroutines requires multiple threads.

Does Go have multithreading?

No, Golang uses lightweight user-level goroutines instead of operating system threads for concurrency. This provides more efficiency and control compared to multithreading. The golang runtime handles scheduling goroutines across OS threads.

Conclusion

Golang’s goroutines and channels provide a simple yet powerful concurrent programming model. They make it easy to build scalable & maintainable concurrent software.

Some additional concurrency features in Golang:

  • sync.Mutex for mutual exclusion
  • sync.WaitGroup for waiting on goroutine groups
  • context.Context for cancellation signals

With these primitives, you can build sophisticated concurrent programs and take advantage of multi-core processors in Golang.

Leave a Reply

Your email address will not be published. Required fields are marked *