Home > database >  Does using `runtime.Gosched()` in the default case of a Select statement make any sense?
Does using `runtime.Gosched()` in the default case of a Select statement make any sense?

Time:06-10

Go's documentation says that

Gosched yields the processor, allowing other goroutines to run. It does not suspend the current goroutine, so execution resumes automatically.

Based on that definition if I have a series of long running go routines being created and executed concurrently, would it be advantageous to write a select statement the following way:

for {
    select {
        case msg := <- msgch : 
            fmt.Println(msg)
        default: 
            runtime.Gosched()
    }
} 

I assume based on the documentation, this code can result in more go routines being run. Is my assumption correct?

CodePudding user response:

No, it isn't necessary here, because whenever Go is waiting on a channel or waiting for I/O, it allows other goroutines to run automatically. That's been the case since Go 1.0.

In Go 1.2 the Go runtime's scheduler added automatic preemption points whenever you called a function. Prior to that if you had a CPU-bound loop (even with a function call) it could starve the scheduler and you might need runtime.Gosched.

And then in Go 1.14, they made this aspect of the runtime even better, and even tight CPU-bound loops with no functions calls are automatically pre-empted.

So with any Go version, you don't need to call runtime.Gosched when you're just waiting on a channel or on I/O; before 1.14, you may have wanted to call it if you were doing a long-running calculation. But with Go 1.14 , I don't see why you'd ever need to call it manually.


If I was reviewing your actual code, I'd suggest changing it to a simple for ... range loop:

for msg := range msgCh {
    fmt.Println(msg)
}

This will wait for each message to come in and print it, and stop if/when the channel is closed. However, you would want a switch if you're waiting on another channel or done signal, for example a context. Something like this:

for {
    select {
        case msg := <- msgCh:
            fmt.Println(msg)
        case <-ctx.Done():
            return
    }
}

CodePudding user response:

Does using runtime.Gosched() [anywhere] make any sense?

No. It basically is never needed or sensible to use Gosched.

  • Related