Concurrency Patterns in Go
In Go, concurrency patterns are a fundamental part of the language, designed to leverage the simplicity and efficiency of goroutines and channels. Below are some of concurrency patterns in Go:
1. Goroutines
Description: Goroutines are lightweight units of execution that allow functions to run in parallel, making it easier to create concurrent programs. Using the go keyword before a function call executes it as a goroutine.
go func() {
fmt.Println("Running in a goroutine")
}()
2. Channels
Description: Channels enable communication and synchronization between goroutines, securely passing data without the need for complex locks. Channels can be unidirectional or bidirectional and are used with the <- operator.
ch := make(chan int)
go func() {
ch <- 42 // send 42 to the channel
}()
fmt.Println(<-ch) // read from the channel
3. Select Statement
Description: The select statement monitors multiple channels simultaneously, executing the first action that becomes available. It is useful for managing and synchronizing channels in concurrent operations.
select {
case msg := <-ch1:
fmt.Println("Received from ch1:", msg)
case msg := <-ch2:
fmt.Println("Received from ch2:", msg)
default:
fmt.Println("No operations ready")
}
4. Worker Pool
Description: A Worker Pool is used to control the number of goroutines processing tasks concurrently, which is particularly useful for resource-intensive operations.
func worker(id int, jobs <-chan int, results chan<- int) {
for j := range jobs {
fmt.Printf("Worker %d processing job %d\n", id, j)
results <- j * 2
}
}
func main() {
jobs := make(chan int, 100)
results := make(chan int, 100)
// Create 3 workers
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
// Send 5 jobs
for j := 1; j <= 5; j++ {
jobs <- j
}
close(jobs)
for a := 1; a <= 5; a++ {
fmt.Println(<-results)
}
}
5. Fan-Out and Fan-In
Description: This pattern helps distribute tasks among multiple goroutines (Fan-Out) and consolidate results into a single channel (Fan-In).
func main() {
in := make(chan int)
out := make(chan int)
// Fan-Out
go func() {
for i := 0; i < 5; i++ {
in <- i
}
close(in)
}()
// Fan-In
go func() {
for num := range in {
out <- num * 2
}
close(out)
}()
for result := range out {
fmt.Println(result)
}
}
6. Rate Limiting
Description: Sometimes, it's necessary to limit the number of requests or operations processed in a given time frame. In Go, this can be achieved using time.Tick and select.
func main() {
requests := make(chan int, 5)
for i := 1; i <= 5; i++ {
requests <- i
}
close(requests)
limiter := time.Tick(200 * time.Millisecond)
for req := range requests {
<-limiter
fmt.Println("Processing request", req, time.Now())
}
}
7. Pipeline
Description: The pipeline pattern connects a series of stages where each stage processes data and passes it to the next stage. Great for data transformation or processing workflows. Each stage runs in its own goroutine, linked by channels for communication.
func gen(nums ...int) <-chan int {
out := make(chan int)
go func() {
for _, n := range nums {
out <- n
}
close(out)
}()
return out
}
func square(in <-chan int) <-chan int {
out := make(chan int)
go func() {
for n := range in {
out <- n * n
}
close(out)
}()
return out
}
func main() {
nums := gen(1, 2, 3, 4)
squares := square(nums)
for sq := range squares {
fmt.Println(sq)
}
}
Benefits of Concurrency Patterns in Go
These patterns allow Go to maintain efficiency and low resource usage while handling multiple simultaneous operations. By combining lightweight goroutines, efficient channels, and flow control mechanisms like select, Go stands out as an effective language for building concurrent and scalable systems.
Fullstack Developer | Senior Engineer | Node.js | React | Typescript | AWS
7moVery important topic!
Senior iOS Engineer | Swift | SwiftUI | UIKit
8moGreat breakdown of concurrency patterns in Go!
Gen AI | LLMs | RAG | AI Solutions Architecture | MLOps & AIOps | Kotlin | Go | Flutter | .NET 8 | Java | Hexagonal Arch | gRPC | Docker | K8s | Terraform | Vertex AI | AWS | GCP | Azure | Hands-on AI in Production
8moInsightful
Senior Software Engineer | Node.js | AWS | LLM | React.js | Clean Architecture | DDD
8moGreat content. Thank you for sharing.
Data Scientist | Machine Learning | Computer Vision | Deep Learning | LLM | RAG | Python
8moVery informative!