I\'m trying to understand concurrency in Go. In particular, I wrote this thread-unsafe program:
package main
import
According to this and this, some calls can't invoke during a CPU-bound Goroutine (if the Goroutine never yields to the scheduler). This can cause other Goroutines to hang if they need to block the main thread (such is the case with the write()
syscall used by fmt.Println()
)
The solution I found involved calling runtime.Gosched() in your cpu-bound thread to yield back to the scheduler, as follows:
package main
import (
"fmt"
"runtime"
)
var x = 1
func inc_x() {
for {
x += 1
runtime.Gosched()
}
}
func main() {
go inc_x()
for {
fmt.Println(x)
}
}
Because you're only performing one operation in the Goroutine, runtime.Gosched()
is being called very often. Calling runtime.GOMAXPROCS(2)
on init is faster by an order of magnitude, but would be very thread-unsafe if you were doing anything more complicated than incrementing a number (for example, dealing with arrays, structs, maps, etc).
In that case, best practice would potentially be using a channel to manage shared access to a resource.
Update: As of Go 1.2, any non-inlined function call can invoke the scheduler.