[The other responses have been excellent, but I wanted to point one thing out.]
On Fri, Feb 22, 2019 at 3:17 AM Jingguo Yao <yaojing...@gmail.com> wrote: > Consider the following code which launches two goroutines. Each > goroutine uses a for loop to print messages. > > package main > > import ( > "fmt" > "runtime" > "time" > ) > > func main() { > count := runtime.GOMAXPROCS(1) > fmt.Printf("GOMAXPROCS: %d\n", count) > > // goroutine 1 > go func() { > for { > fmt.Printf("1") > } > }() > > // goroutine 2 > go func() { > for { > fmt.Printf("2") > } > }() > > time.Sleep(20 * time.Second) > } > > The code uses runtime.GOMAXPROCS(1) to make the Go runtime has only > one processor (P). So there is only one OS thread (M) to run > goroutines. Without preemption, the M will run goroutine 1 or > goroutine 2 continuously. The messages sent to the terminal should be > all 1s or all 2s. But running the code prints interleaved 1s and 2s to > the terminal, which means that some preemption happens. But > > https://www.quora.com/How-does-the-golang-scheduler-work/answer/Ian-Lance-Taylor > says that: > > > A G can only be pre-empted at a safe point, which in the current > > implementation can only happen when the code makes a function call. > > Since both goroutines do not make any function calls, there should be > some other way to preempt a G. Can anyone give me an explanation of > such kind of preemption? > Not only is fmt.Printf a function call, but it makes a blocking syscall (write specifically), which gives the go runtime license to spin up a new OS thread and immediately schedule the other goroutine. runtime.GOMAXPROCS(1) only tries to guarantee that one OS thread executing Go code will be executing at a time. (this has no bearing on the revised version without a call to fmt.Printf().) > > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.