3

Understanding GPM

Implementation principle of scheduler in Go language

There are four main structures that support the entire scheduler implementation in the Go language, namely G, P, M, and Sched. The first three are defined in runrtime.h, and Sched is defined in proc.c.

  • The Sched structure is the scheduler, which maintains the queues that store M and G, as well as all the state information of the scheduler
  • G is the core structure of goroutine implementation. It is the encapsulation of a task to be executed concurrently. It can be called a user-mode thread. It belongs to user-level resources, is transparent to the operating system, is lightweight, can be created in large quantities, and has low context switching costs. .
  • P is a processor, a logical processor. Its main function is to manage G objects and provide localized resources for G to run on M. It maintains a goroutine queue runqueue, which can also be understood as the context of goroutines.
  • M is Machine, which is an operating system thread entity created by system calls. Its function is to execute concurrent tasks in G. It represents a kernel thread and is managed by the operating system. Goroutine is running on M, and small objects are maintained in M. Information such as memory mcache, currently executing goroutine, random number generator, etc.

runtime package

The runtime is similar to the virtual machine in Java or .Net, responsible for memory allocation, garbage collection, goroutine, channel, slice, map, reflection, etc.

Common functions of the runtime package

 package main

import (
    "fmt"
    "runtime"
)

func main() {
    //获取goroot目录
    fmt.Println("GOROOT: ", runtime.GOROOT())
    //获取操作系统
    fmt.Println("os/platform: ", runtime.GOOS)
    //获取当前逻辑cpu的数量,当然也可以用runtime.GOMAXPROCS()手动设置逻辑CPU的数量,不过GO1.8之后不用设置,默认运行在多核
    fmt.Println("逻辑cpu的数量: ", runtime.NumCPU())
    //GOsched: 让当前的额goroutine让出当前的时间片,当一个goroutine发生阻塞的时候,go会把所有和这个阻塞goroutine处于
    //同一个系统线程中的其他goroutine移植到其他系统线程上从而使之不被阻塞。
    go func() {
        for i := 0; i < 3; i++ {
            fmt.Println("goproutine")
        }
    }()
    for i := 0; i < 3; i++ {
        //让出时间片,让其他goroutine先执行
        runtime.Gosched()
        fmt.Println("...........................main")
    }
}
 package main

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

func main() {

    go func() {
        fmt.Println("goroutine开始")
        //调用fun
        fun()
        fmt.Println("goroutine结束")
    }()
    //为了主程序不结束 我们让他睡一会
    time.Sleep(3 * time.Second)
}

func fun() {
    defer fmt.Println("defer job")
    runtime.Goexit() //终止当前的goroutine
    fmt.Println("fun函数")
}

There are many others, you can check the official documentation when you use it: https://golang.google.cn/pkg/

Reference: bilibili


LiberHome
409 声望1.1k 粉丝

有问题 欢迎发邮件 📩 liberhome@163.com