Concurrency Patterns
Worker Pool Pattern
func workerPool(jobs <-chan int, results chan<- int) {
for job := range jobs {
results <- processJob(job)
}
}
func main() {
jobs := make(chan int, 100)
results := make(chan int, 100)
// Create worker pool
for w := 1; w <= 3; w++ {
go workerPool(jobs, results)
}
// Send jobs
for j := 1; j <= 5; j++ {
jobs <- j
}
close(jobs)
// Collect results
for a := 1; a <= 5; a++ {
<-results
}
}
Concurrency Patterns Overview
Pattern |
Description |
Use Case |
Worker Pool |
Distribute tasks across multiple workers |
Parallel processing |
Fan-Out/Fan-In |
Multiple goroutines producing, single goroutine consuming |
Data aggregation |
Pipeline |
Series of stages connected by channels |
Data transformation |
Fan-Out/Fan-In Pattern
graph TD
A[Input] --> B[Goroutine 1]
A --> C[Goroutine 2]
A --> D[Goroutine 3]
B --> E[Aggregator]
C --> E
D --> E
Pipeline Pattern Implementation
func generator(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
}
Timeout Pattern
func timeoutExample() {
ch := make(chan int)
go func() {
time.Sleep(2 * time.Second)
ch <- 42
}()
select {
case result := <-ch:
fmt.Println("Received:", result)
case <-time.After(1 * time.Second):
fmt.Println("Operation timed out")
}
}
Context-Based Cancellation
func longRunningTask(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("Task cancelled")
return
default:
// Do work
}
}
}
Synchronization Primitives
Primitive |
Purpose |
Use Case |
Mutex |
Mutual Exclusion |
Protecting shared resources |
WaitGroup |
Waiting for goroutines |
Coordinating concurrent operations |
Once |
One-time initialization |
Singleton pattern |
Advanced Concurrency Techniques
func rateLimiting() {
requests := make(chan int, 5)
limiter := time.Tick(200 * time.Millisecond)
for req := range requests {
<-limiter
go processRequest(req)
}
}
LabEx Recommendation
Mastering concurrency patterns takes practice. LabEx offers interactive environments to experiment with these advanced Go techniques.
Common Concurrency Challenges
- Race conditions
- Deadlocks
- Resource contention
- Proper error handling in concurrent code
- Minimize shared state
- Use channels for communication
- Avoid unnecessary synchronization
- Profile and benchmark concurrent code