M:N Scheduler

  • The Go scheduler is part of the Go runtime. It is known as M:N scheduler.
  • Go scheduler runs in user space
  • Go scheduler use OS threads to schedul goroutines for execution.
  • Goroutines runs in the context of os threads.
  • Go runtime create number of worker OS threads, equal to GOMAXPROCS.
  • GOMAXPROCS - default value is number of processors on machine.
  • Go scheduler distributes runnable goroutines over multiple worker OS threads.
  • At any time, N goroutines could be scheduled on M OS threads that runs on at most GOMAXPROCS numbers of processors.

Asynchronous Preempation(搶佔)

  • As of Go 1.14. Go scheduler implements asynchronous preemption.
  • This prevents long running Goroutines form hogging onto CPU, that could block other Goroutines.
  • The asynchronous preemption triggered based on a time condition. When a goroutine is running for more than 10ms, Go will to preempt it.

Image

MPG

在 n 個操作系統線程上多工調度 m 個 Goroutines

G: Goroutine M: Machine 或 worker thread P: Processor, 只有當M與一個P關聯後才能執行Go程式碼

深色的G:待執行狀態 淺色G: 正在執行

當一個P關聯多個G時, 就會處理G的執行順序, 就是並發. 當一個P在執行一個協程工作時, 其他的會在等待, 當正在執行的協程遇到阻塞情況, 例如IO操作等, go的處理器就會去執行其他的協程, 因為對於類似IO的操作, 處理器不知道你需要多久才能執行結束, 所以他不回去等你執行完。

上面我們看著go的並發好像是搶占式的, 事實上go的協程是非搶占式的, 由協程主動交出控制權, 也就是說, 上面在發生IO操作時, 並不是調度器強制切換執行其他的協程, 而是當前協程交出了控制權, 調度器才去執行其他協程。 我們列舉一下goroutine可能切換的點:

  • I/O, select
  • channel
  • 等待鎖
  • runtime.Gosched()

這些點是go協程可能切換的地方,但是並不是一定切換的。

正是因為是非搶占式的,所以才輕鬆的構造上萬的協程, 如果是搶占式,那麼就會在切換任務時,保存當前的上下文環境, 因為當前線程如果正在做一件事,做到一半,我們就強制停止,這時我們就必須多保存很多信息,避免再次切換回來時任務出錯. Image

This browser does not support PDFs.
Please download the PDF to view it: Download PDF.

Reference

© Kimi Tsai all right reserved.            Updated : 2023-07-12 09:04:54

results matching ""

    No results matching ""

    results matching ""

      No results matching ""