I'm using an open source package that leverage the runtime.Gosched()
to wait for a resource to be available. And found it may cause a high CPU usage. The code can be simplified to be like this:
func wait() {
for {
// check if something is available, and return it when available.
// if size > oldSize {
// return buffer[oldSize:size-1]
// }
// In my case there's no write to the buffer for quite a long time
// so that it keep arriving at this Gosched calling
runtime.Gosched()
}
}
func run() {
for i := 0; i < 20; i++ {
go wait()
}
time.Sleep(time.Second*20)
}
I have observed that it took all the CPU resource available when running the run() function. However, when using a channel, as the following code, there is no such problem.
func waitForChannel(ch chan struct{}) {
<- ch
}
func runWithChannel() {
ch := make(chan struct{})
for i := 0; i < 20; i++ {
go waitForChannel(ch)
}
time.Sleep(time.Second*20)
//close(ch)
}
I know that I should use channels, when I want to wait for a resource and yield the current processor. However I can't find an explanation of the difference of waiting for a channel and calling Gosched over and over again. And what's the use case of Gosched, if it's not suitable for this situation.