Reputation: 85545
A select blocks until one of its cases can run, then it executes that case.
I was testing select
case, and I got an unexpected result:
func main() {
channel1 := make(chan string)
channel2 := make(chan string)
go func() {
for i := 0; i < 5; i++ {
channel1 <- "I'll print every 100ms"
time.Sleep(time.Millisecond * 100)
}
}()
go func() {
for i := 0; i < 5; i++ {
channel2 <- "I'll print every 1s"
time.Sleep(time.Second * 1)
}
}()
for i := 0; i < 5; i++ {
select {
case message1 := <-channel1:
fmt.Println(message1)
case message2 := <-channel2:
fmt.Println(message2)
}
}
}
Most of the time it printed 1s
and this is perfect with goroutines. But once it printed 1s
in between the 100ms
:
/*
$ go run .
I'll print every 1s
I'll print every 100ms
I'll print every 100ms
I'll print every 100ms
I'll print every 100ms
$ go run .
I'll print every 1s
I'll print every 100ms
I'll print every 100ms
I'll print every 100ms
I'll print every 100ms
$ go run .
I'll print every 1s
I'll print every 100ms
I'll print every 100ms
I'll print every 100ms
I'll print every 100ms
$ go run .
I'll print every 1s
I'll print every 100ms
I'll print every 100ms
I'll print every 100ms
I'll print every 100ms
$ go run . # WHY 1s IS EXCECUTED IN BETWEEN?
I'll print every 100ms
I'll print every 1s # HERE?
I'll print every 100ms
I'll print every 100ms
I'll print every 100ms
$ go run .
I'll print every 1s
I'll print every 100ms
I'll print every 100ms
I'll print every 100ms
I'll print every 100ms
$ go run .
I'll print every 1s
I'll print every 100ms
I'll print every 100ms
I'll print every 100ms
I'll print every 100ms
$ go run .
I'll print every 1s
I'll print every 100ms
I'll print every 100ms
I'll print every 100ms
I'll print every 100ms
*/
As per the select
statement, I expected it to result because it selected 100ms
first:
/*
# Either
I'll print every 100ms
I'll print every 100ms
I'll print every 100ms
I'll print every 100ms
I'll print every 1s
# Or
I'll print every 100ms
I'll print every 1s
# But not:
I'll print every 100ms
I'll print every 1s
I'll print every 100ms
I'll print every 100ms
I'll print every 100ms
*/
Or, am I misunderstanding select
statement?
Upvotes: 0
Views: 87
Reputation: 12928
You are sending on the channel before you sleep, so which one comes first depends on which of the goroutines are faster to start up and run.
If you have a select where multiple cases are ready, the order is random.
Upvotes: 4