Practical Golang Channel Examples
Now that we've covered the fundamentals and advanced techniques of Golang channels, let's explore some practical examples of how they can be used in real-world applications.
Producer-Consumer Pattern
One common use case for channels is the producer-consumer pattern, where one or more producer goroutines generate data and send it to a channel, and one or more consumer goroutines receive and process the data.
// Producer function
func producer(ch chan int) {
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
}
// Consumer function
func consumer(wg *sync.WaitGroup, ch chan int) {
defer wg.Done()
for value := range ch {
fmt.Println("Consumed:", value)
}
}
func main() {
ch := make(chan int)
var wg sync.WaitGroup
wg.Add(2)
go producer(ch)
go consumer(&wg, ch)
wg.Wait()
}
Throttling with Channels
Channels can be used to implement throttling, which is the process of limiting the rate at which tasks are executed. This can be useful for managing resource usage, preventing overload, and ensuring fairness.
// Throttle function
func throttle(tasks <-chan int, limit int) {
sem := make(chan struct{}, limit)
for task := range tasks {
sem <- struct{}{}
go func(task int) {
defer func() { <-sem }()
// Execute the task
fmt.Println("Executing task:", task)
}(task)
}
}
func main() {
tasks := make(chan int, 10)
for i := 0; i < 10; i++ {
tasks <- i
}
close(tasks)
throttle(tasks, 3)
}
Cancellation with Channels
Channels can be used to implement cancellation, which allows you to stop the execution of a long-running task or a set of tasks when they are no longer needed.
// Worker function
func worker(wg *sync.WaitGroup, ch <-chan struct{}) {
defer wg.Done()
for {
select {
case <-ch:
fmt.Println("Worker received cancellation signal")
return
default:
// Perform the work
time.Sleep(1 * time.Second)
fmt.Println("Worker is working")
}
}
}
func main() {
var wg sync.WaitGroup
cancel := make(chan struct{})
for i := 0; i < 3; i++ {
wg.Add(1)
go worker(&wg, cancel)
}
time.Sleep(3 * time.Second)
close(cancel)
wg.Wait()
}
These examples demonstrate how Golang channels can be used to solve real-world concurrency problems and build efficient, scalable, and maintainable applications.