GO并发|青训营笔记

59 阅读2分钟

Go并发机制 ​ 协程:一个线程可以对应多个协程,协程串行运行在用户空间。协程运行在线程之上,当一个协程执行完成后,可以选择主动让出,让另一个协程运行在当前线程之上。协程并没有增加线程数量,只是在线程的基础之上通过分时复用的方式运行多个协程,而且协程的切换在用户态完成,切换的代价比线程从用户态到内核态的代价小很多。

​ Go摒弃线程、进程、协程,提出goroutine:

M(machine):一个M代表一个内核线程(与KSE一一对应) P(processor):一个P代表执行一个Go代码片段所必须的资源(上下文环境) G(goroutine):一个G代表一个Go代码片段。 ​ 一个M与一个P关联之后,就形成一个G的运行环境(内核线程+上下文环境)。M与KSE一对一,M与P总是一对一(当一个M因系统调用阻塞(运行的G进入系统调用),此时P会与M分离开来,并与新建/空闲的M关联),P与G一对多

M、P、G

——M(Machine)

​ 系统维护一个全局M列表(runtime.allm) 调度器维护一个空闲M列表(runtime.sched.midle)

——P(Processor)

​ 系统维护一个全局P列表(runtime.allp) 调度器维护一个空闲P列表(runtime.sched.pidle)

​ 每个P维护一个可运行G队列(runtime.p.runq)(队列满则会分出一半给调度器可运行G队列)与一个自由G列表(runtime.p.gfree)(已经运行完成的G,在欲启用一个go语句时,会复用该列表中的G。当P中的自由G列表元素过多或过少时,调度器的自由G列表会与其进行转移)