Let's take this example from the GoTour, as it illustrates my problem with processing SDL events only when there are events.
package main
import (
"fmt"
"time"
)
func main() {
tick := time.Tick(1e8)
boom := time.After(5e8)
for {
select {
case <-tick:
fmt.Println("tick.")
case <-boom:
fmt.Println("BOOM!")
return
default:
fmt.Println(" .")
time.Sleep(5e7)
}
}
}
This works. But what if I don't want to print or sleep in the default case, but just want to keep looping? I tried this:
case <-boom:
fmt.Println("BOOM!")
return
default: // Nothing here.
}
}
}
but it blocks.
I have seen here and there a sentence about goroutines scheduling, but I didn't understand them. So I guess I have two questions:
1) Why does it block?
2) How do I make it do nothing without blocking?
Your Original Example produces this
.
.
tick.
.
.
tick.
.
.
tick.
.
.
tick.
.
.
tick.
BOOM!
Wheraeas Your Second Example produces this
[process took too long]
The difference is what you did in the default
case. A default
case is always ready to run so a select
with a default statement in it never blocks. The second example runs round the loop continuously choosing one of the branches (case or default) that is ready to run. You are now wondering why the the timer never fires. That is because go routines are not pre-emptively scheduled. So because the loop below never does any IO, the time ticks never fire.
for {
select {
// whatever
default:
}
}
There are a number of ways of fixing this. Firstly you can put some IO in like you did in your first example. Or you could put a runtime.Gosched() in. Or you could allow the go runtime to use more than one thread with runtime.GOMAXPROCS(2) all of which will work.
The best way IMHO is to leave out the default statement entirely like this. A select without a default statement will block until one of the case statements is ready. If you want to do some background processing (that you were doing in the default statement) then start a goroutine - that is the go way!
In fact I've seen so many problems with default in select statements that I'd be tempted to say to never use them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With