美文网首页
golang协程调度模式解密

golang协程调度模式解密

作者: ScienBeast | 来源:发表于2021-08-07 19:38 被阅读0次

golang学习笔记 https://github.com/piao100101/coding-with-go

协程

优势

频繁创建线程会造成不必要的开销,所以才有了线程池。在线程池中预先保存一定数量的线程,新任务发布到任务队列,线程池中的线程不断地从任务队列中取出任务并执行,可以有效的减少创建和销毁带来的开销。

过多的线程会导致争抢cpu资源,且上下文的切换的开销变大。而工作在用户态的协程能大大减少上下文切换的开销。协程调度器把可运行的协程逐个调度到线程中执行,同时即时把阻塞的协程调度出协程,从而有效地避免了线程的频繁切换,达到了少量线程实现高并发的效果。

多个协程分享操作系统分给线程的时间片,从而达到充分利用CPU的目的,协程调度器决定了则决定了协程运行的顺序。每个线程同一时刻只能运行一个协程。

调度模型

go调度模型包含三个实体:

  • M(machine) 工作线程由操作系统调度。
  • P(processor) 处理器不是指cpu,包含运行go代码必要资源也负责调度groutine。
  • G(groutine) Go协程
    M必须持有P才可以执行代码,P默认情况下等同于cpu核数,负责调度groutine队列。
    M1->P1->G...
    M2->P2->G...

队列轮转

每个处理器维护者一个协程G的队列,处理器依次将协程G调度到M中执行。
每个P会周期性地查看全局队列中是否有G待运行并将其调度到M中执行,全局队列中的G主要来自系统调用中恢复的G.

系统调用

如果协程发起系统调用,则整个工作线程M被阻塞,协程队列中的其他协程都会阻塞。

一般情况下M的个数会略大于P个数,多出来的M将会在G产生系统调用时发挥作用。与线程池类似,Go也提供M池子。当协程G1发起系统掉用时,M1会释放P,由M1->P->G1 G2 ...转变成 M1->G1, M2会接管P的其他协程M2->P->G2 G3 G4...
冗余的M可能来源于缓存池,也可能是新建的。

当G1结束系统调用后,根据M1是否获取到P,进行不用的处理。

  • 有空闲P,则获取继续执行。
  • 没有空闲P,放入全局队列等待其他P调度。然后将M1放入缓存池睡眠。

工作量窃取

多个处理P维护队列可能不均衡,导致部分处理器非常繁忙,而其余相对空闲。产生原因是有些协程自身不断地派生协程。

为此Go调度器提供了工作量窃取策略,当某个处理器P没有需要调度的协程时,将从其他处理中偷取协程,每次偷取一半。

抢占式调度

抢占式调度,是指避免某个协程长时间执行,而阻碍其他协程被调度的机制。
调度器监控每个协程执行时间,一旦执行时间过长且有其他协程等待,会把协程暂停,转而调度等待的协程,以达到类似时间片轮转的效果。比如for循环会一直占用执行权。

GOMAXPROCS对性能影响。

在IO密集型应用,GOMAXPROCS大小设置大一些,获取性能会更好。
IO密集型会经常发生系统调用,会有一个新的M启用或创建,但由于Go调度器检测M到被阻塞有一定延迟。如果P数量多,则P管理协程队列会变小。

相关文章

  • golang协程调度模式解密

    golang学习笔记 https://github.com/piao100101/coding-with-go[h...

  • golang 协程调度

    前言 Goroutine调度是一个很复杂的机制,尽管Go源码中提供了大量的注释,但对其原理没有一个好的理解的情况下...

  • go-ethereum事件机制设计与实现

    总体介绍 以太坊内部有大量协程,协程间的调度驱动通过事件机制来完成;具体实现使用golang的chan机制。主要方...

  • Golang协程调度器

    说在前面 Golang作为Google亲自孵化出来一门现代编程语言,可以说是吸收了众多早期编程语言的优点,又有其自...

  • 【深度知识】Golang协程调度:协程状态

    状态总览 在讲解操作系统进程调度的部分时,几乎所有的书籍都会先列出一张进程的状态迁移图,通过状态图,能很清晰的把进...

  • 3.协程的调度(1)

    上一张通过四种启动模式,我们知道只有调度器ok,才能执行协程里面的代码,那么协程是如何调度的?下面是Corouti...

  • golang协程调度面试总结

    1.go的GMP模型 goroutine运行在用户态,是由runtime来控制调度的,调度过程中主要涉及到三个对象...

  • [Android] 深入理解Kotlin协程

    Kotlin协程 协程由程序自己创建和调度,不需要操作系统调度,所以协程比线程更加轻量。相比于线程的切换,协程切换...

  • 协程

    协程与线程 线程的调度是由操作系统负责,协程调度是程序自行负责 与线程相比,协程减少了无谓的操作系统切换 协程实际...

  • 浅谈GoLang协程

    GoLang协程 学习golang也有一段时间了,这里讲一下自己对golang协程的使用理解,golang很多人都...

网友评论

      本文标题:golang协程调度模式解密

      本文链接:https://www.haomeiwen.com/subject/hjugvltx.html