Skip to main content

Golang Concurrency #5 - Select

Published 1 min readMarkdown
Golang Concurrency #5 - Select

Select statement

Select lets you wait on multiple channel operations at once. It picks whichever channel is ready first.

Basic syntax

select {
case value := <-ch1:
    // Handle ch1
case value := <-ch2:
    // Handle ch2
}

Key clarifications

1. Select runs exactly once

2. If multiple cases are ready, select picks randomly (not chronological order).

3. Select with sending

select {
case ch1 <- "hello":  // Try to send
    fmt.Println("Sent to ch1")
case msg := <-ch2:    // Try to receive
    fmt.Println("Got from ch2")
}

Select tries both operations. Whichever can happen first, happens. Sending only works if there's buffer space or a receiver waiting.

4. Default case (non-blocking)

select {
case msg := <-ch:
    fmt.Println("Got message")
default:
    fmt.Println("No message ready")  // Runs immediately if ch not ready
}

Without default, select blocks until a channel is ready. With default, it never blocks.

5. Why receivers usually need goroutines

ch := make(chan int)
ch <- 42        // BLOCKS forever - no receiver ready
value := <-ch   // Never executes

With unbuffered channels, sender and receiver must be in different goroutines because they need to "meet" simultaneously.

Common timeout pattern

select {
case result := <-ch:
    fmt.Println("Got result")
case <-time.After(5 * time.Second):
    fmt.Println("Timeout!")
}

About the author

  • Just a guy who loves to write code and watch anime.

No comments yet. Be the first to comment.