CodeBlanks Logo Icon CodeBlanks

Preemption

Learn how the Go scheduler forcibly suspends goroutines.

Preemption

If a goroutine holds a P too long, others starve. Since Go 1.14 the scheduler uses asynchronous preemption: a monitor called sysmon sends a signal to the thread of a goroutine running longer than 10 ms and stops it at a safe point.

go func() {
    for {}  // before Go 1.14 this could hold the P forever
}()

Previously preemption could only happen at function calls; tight loops could freeze the whole program.

Cooperative points

Besides preemption, goroutines also release the P on their own: channel operations, locks, time.Sleep, network I/O and runtime.Gosched(). The stack-growth check at every function entry also acts as a preemption point. That's why in real programs goroutines change hands often.

Practice Running beside a tight loop

Set runtime.GOMAXPROCS(1). Start an infinite for {} loop in a goroutine. Then call time.Sleep(20 * time.Millisecond) and print fmt.Println("main devam etti"). Thanks to preemption the program doesn't freeze.

Starter code

main.go
package main

import (
    "fmt"
    "runtime"
    "time"
)

func main() {
    // buraya yaz
}

Sample solution

main.go
package main

import (
    "fmt"
    "runtime"
    "time"
)

func main() {
    runtime.GOMAXPROCS(1)
    go func() {
        for {
        }
    }()
    time.Sleep(20 * time.Millisecond)
    fmt.Println("main devam etti")
}

Expected output

main devam etti

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What mechanism triggers asynchronous preemption?

  • The GC finishing
  • A channel closing
  • A signal sent to the thread by sysmon Correct answer
  • The stack check in a function call

Explanation: On Unix SIGURG is used; the signal handler saves the goroutine's context and returns to the scheduler.

2 Time threshold

Question
const forcePreemptNS = ____ * 1000 * 1000
Answer
const forcePreemptNS = 10 * 1000 * 1000

Explanation: The Go scheduler's time slice is about 10 ms.

3 Way to yield

Term Meaning
Waiting on a channel Cooperative
runtime.Gosched Voluntary yield
Sinyal (SIGURG) Async preemption
Function entry Stack-check point

All lessons in Expert