0
0
Goprogramming~5 mins

Select with multiple channels in Go

Choose your learning style9 modes available
Introduction

Using select with multiple channels lets your program wait for many things at once and react to whichever happens first.

When you want to listen to multiple sources of data at the same time.
When you want to handle different events without blocking your program.
When you want to wait for messages from several channels and respond to the first one ready.
When you want to add a timeout to waiting for channel messages.
When you want to cleanly stop goroutines by listening to a done channel.
Syntax
Go
select {
case val1 := <-chan1:
    // handle val1
case val2 := <-chan2:
    // handle val2
case chan3 <- val3:
    // send val3
default:
    // optional: run if no channel is ready
}

Each case must be a send or receive operation on a channel.

The default case runs if no other channel is ready, so it prevents blocking.

Examples
Waits for a message from either ch1 or ch2 and prints it.
Go
select {
case msg := <-ch1:
    fmt.Println("Received from ch1:", msg)
case msg := <-ch2:
    fmt.Println("Received from ch2:", msg)
}
Tries to send 10 to ch1. If it can't send immediately, runs the default case.
Go
select {
case ch1 <- 10:
    fmt.Println("Sent 10 to ch1")
default:
    fmt.Println("No channel ready to send")
}
Waits for a message from ch or times out after 1 second.
Go
select {
case <-time.After(time.Second):
    fmt.Println("Timeout after 1 second")
case msg := <-ch:
    fmt.Println("Received:", msg)
}
Sample Program

This program creates two channels and sends messages to them after different delays. The select waits for messages from both channels and prints them as they arrive.

Go
package main

import (
	"fmt"
	"time"
)

func main() {
	ch1 := make(chan string)
	ch2 := make(chan string)

	// Send messages after some time
	go func() {
		time.Sleep(2 * time.Second)
		ch1 <- "hello from ch1"
	}()

	go func() {
		time.Sleep(1 * time.Second)
		ch2 <- "hello from ch2"
	}()

	for i := 0; i < 2; i++ {
		select {
		case msg1 := <-ch1:
			fmt.Println("Received:", msg1)
		case msg2 := <-ch2:
			fmt.Println("Received:", msg2)
		}
	}
}
OutputSuccess
Important Notes

If multiple channels are ready, select picks one at random.

Use default to avoid blocking if no channels are ready.

Remember to close channels if needed to avoid goroutine leaks.

Summary

Select lets you wait on multiple channels at once.

It runs the code for the first channel ready to send or receive.

You can add a default case to do something if no channels are ready.