Select waits on a group of channels

yourbasic.org/golang

The select statement waits for multiple send or receive opera­tions simul­taneously.

// blocks until there's data available on ch1 or ch2
select {
case <-ch1:
    fmt.Println("Received from ch1")
case <-ch2:
    fmt.Println("Received from ch2")
}

Send and receive operations on a nil channel block forever. This can be used to disable a channel in a select statement:

ch1 = nil // disables this channel
select {
case <-ch1:
    fmt.Println("Received from ch1") // will not happen
case <-ch2:
    fmt.Println("Received from ch2")
}

Default case

The default case is always able to proceed and runs if all other cases are blocked.

// never blocks
select {
case x := <-ch:
    fmt.Println("Received", x)
default:
    fmt.Println("Nothing available")
}

Examples

An infinite random binary sequence

As a toy example you can use the random choice among cases that can proceed to generate random bits.

rand := make(chan int)
for {
    select {
    case rand <- 0: // no statement
    case rand <- 1:
    }
}

A blocking operation with a timeout

The function time.After is part of the standard library; it waits for a specified time to elapse and then sends the current time on the returned channel.

select {
case news := <-AFP:
    fmt.Println(news)
case <-time.After(time.Minute):
    fmt.Println("Time out: No news in one minute")
}

A statement that blocks forever

A select statement blocks until at least one of it’s cases can proceed. With zero cases this will never happen.

select {}

A typical use would be at the end of the main function in some multithreaded programs. When main returns, the program exits and it does not wait for other goroutines to complete.

Share this page: