Concurrency with Select
Implementing Concurrent Patterns
1. Worker Pool Design
func workerPool(jobs <-chan int, results chan<- int) {
for job := range jobs {
results <- processJob(job)
}
}
func concurrentWorkerPool() {
jobs := make(chan int, 100)
results := make(chan int, 100)
for w := 0; w < 3; w++ {
go workerPool(jobs, results)
}
// Distribute jobs
for j := 0; j < 5; j++ {
jobs <- j
}
close(jobs)
// Collect results
for a := 0; a < 5; a++ {
<-results
}
}
Concurrent Communication Strategies
2. Fan-In Pattern
func fanInPattern(ch1, ch2 <-chan int) <-chan int {
merged := make(chan int)
go func() {
for {
select {
case v := <-ch1:
merged <- v
case v := <-ch2:
merged <- v
}
}
}()
return merged
}
Concurrency Pattern Comparison
Pattern |
Description |
Use Case |
Worker Pool |
Distribute tasks across multiple workers |
Parallel processing |
Fan-In |
Merge multiple channels into one |
Aggregating data streams |
Pub-Sub |
Multiple subscribers to a channel |
Event-driven systems |
Advanced Concurrency Techniques
graph TD
A[Concurrent Programming] --> B[Select-Based Patterns]
B --> C[Worker Pools]
B --> D[Fan-In/Fan-Out]
B --> E[Cancellation Mechanisms]
3. Graceful Shutdown
func gracefulShutdown(ctx context.Context, cancel context.CancelFunc) {
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
go func() {
select {
case <-sigChan:
fmt.Println("Received shutdown signal")
cancel()
case <-ctx.Done():
return
}
}()
}
Concurrency Best Practices
- Use channels for communication
- Leverage
select
for complex synchronization
- Implement timeouts and cancellation
- Avoid shared memory when possible
func optimizedConcurrentSearch(data []int, target int) bool {
results := make(chan bool, len(data))
for _, val := range data {
go func(v int) {
if v == target {
results <- true
}
}(val)
}
select {
case <-results:
return true
case <-time.After(time.Second):
return false
}
}
Key Takeaways
select
enables sophisticated concurrent patterns
- Channels provide safe communication between goroutines
- Proper design prevents race conditions and deadlocks
At LabEx, we recommend continuous practice to master Go's concurrency model.