弄懂goroutine调度原理

goroutine简介

golang语言作者Rob Pike说,“Goroutine是一个与其他goroutines 并发运行在同一地址空间的Go函数或方法。一个运行的程序由一个或更多个goroutine组成。它与线程、协程、进程等不同。它是一个goroutine“

  • goroutine通过通道来通信,而协程通过让出和恢复操作来通信;
  • goroutine 通过Golang 的调度器进行调度,而协程通过程序本身调度;

简单的说就是Golang自己实现了协程并叫做goruntine(本文称Go协程),且比协程更强大。

goroutine调度原理

上面说到Go协程是通过Golang的调度器进行调度的,其中调度器的线程模型为两级线程模型。

有关两级线程模型的介绍,可以看这篇文章

我们来看下Golang实现的两级线程模型是怎样的。首先要知道这三个字母代表的含义

  • M:代表内核级的线程
  • P:全程Processor,代表运行Go协程所需要的资源(上下文环境)
  • G:代表Go协程
    图一
    我们先看下为实现调度Golang定义了这些数据结构存M,P,G
名称作用范围描述
全局M列表Go的运行时存放所有M的单向链表
全局P列表Go的运行时存放所有P的数组
全局G列表Go的运行时存放所有G的切片
调度器的空闲M列表调度器存放空闲M的单向链表
调度器的空闲P列表调度器存放空闲P的单向链表
调度器的自由G列表调度器存放自由G的单向链表(有两个)
调度器的可运行G队列调度器存放可运行G的队列
P的自由G列表本地P存放当前P中自由G的单向链表
P的可运行G队列本地P存放当前P中可运行G的队列

然后从上往下解析Go的两级线程模型图

(1)M和内核线程之间是一对一的关系,一个M在其生命周期中,只会和一个内核线程关联,所以不会出现对内核线程的频繁切换;

Golang的运行时执行系统监控和垃圾回收等任务时候会导致创建M,M空闲时不会被销毁,而是放到一个调度器的空闲M列表中,等待与P关联,M默认数量为10000

(2)P和M之间是多对多的关系,P和G之间是一对多的关系,他们的关联是易变的,由Golang的调度器完成调度;

Golang的运行时按规则调度,让P和不同的M建立或断开关联,使得P中的G能够及时获得运行时机

(3)P的数量默认为CPU总核心数,最大为256,当P没有可运行的G时候(P的可运行G队列为空),P会被放到调度器的空闲P列表中,等待M与它关联;

P有可能会被销毁,如运行时用runtime.GOMAXPROCS把P的数量从32降到16时,剩余16个会被销毁,它们原来的G会先转到调度器可运行的G队列自由G列表

(4)每个P中有可运行的G队列(如图中最下面的那行G)和自由G列表(图中未画出来),当G的代码执行完后,该G不会被销毁,而是被放到P的自由G列表调度器的自由G列表。如果程序新建了Go协程,调度器会在自由G列表中取一个G,然后把Go协程的函数赋值到G中(如果自由G列表为空,就创建一个G);

可见Golang调度器在调度时很大程度复用了M,P,G

(5)在Go程序初始化后,调度器首先进行一轮调度,此时用M去搜索可运行的G。其中我们的main函数也是一个G,找到可运行的G后就执行它;

至于怎么找可运行的G呢?答案是到处找,想尽办法找(这里只列出一部分地方)。

  • 本地P的可运行的G队列
  • 调度器的可运行的G队列
  • 其他P的可运行的G队列

(6)P的可运行G队列最大只能存放长度为256的G,当队列满后,调度器会把一半的G转到调度器的可运行G队列

系统监控

上面大概描述了关于goroutine调度的流程。现在还存在一个问题,那就是当Go协程很多(并发量大)时候,显然G是不能一直执行下去的,因为也需要把执行机会留给其他的G。此时Golang运行时的系统监控就起作用了。
一般情况,当G运行时间超过10ms后,该G就会被系统告知需要停止了,让其他G运行。(这里情况比较复杂,并不能确保每个G都能被公平执行)

以下特殊情况该G不需要停止

  • P的可运行G队列为空(没有其他G可运行)
  • 有空闲的M在寻找可运行的G(没有其他G可运行)
  • 空闲的P(还有P闲着)

总结

Golang以两级线程实现模型,自己实现goruntine和调度器,优势在于并行和非常低的资源使用。

主要体现:

  • 内存消耗方面(每个Go协程占的内存远小于线程占的内存)
  • 切换(调度)开销方面
  • 线程切换涉及模式切换(从用户态切换到内核态)

此外,Go协程执行任务完成的顺序并不都是按我们预期的那样(程序不加以控制的情况下),特别在一些耗时较长的任务中。且每个Go协程执行的时间也不是绝对公平的。

如有错误地方,还请狂喷!

转载于:https://www.cnblogs.com/FireworksEasyCool/p/11508806.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/482394.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM-类加载原理

写在前面 我们知道我们编写的java代码,会经过编译器编译成字节码文件(class文件),再把字节码文件装载到JVM中,映射到各个内存区域中,我们的程序就可以在内存中运行了。那么字节码文件是怎样装载到JVM中的呢…

2022年斯坦福AI Index公布:中美主导跨国研究,专利、投资金额暴增

来源:学术头条当地时间 3 月 16 日,斯坦福大学以人为本人工智能研究所(StanfordHAI)正式发布了《2022 年人工智能指数报告》(Artificial Intelligence Index Report 2022)。这是该机构发布的第五份年度报告…

中国传感器规模将超7000亿元:2022最全面深入的产业分析

来源:前瞻经济学人整理:动感传感本文整理自前瞻经济学人的传感器产业报告,作为国内领先的咨询机构,前瞻经济学人的研报分析深度和数据丰富程度,都首屈一指。主要有如下几部分内容:•2022年中国传感器行业市…

强化学习教父Richard Sutton新论文探索决策智能体的通用模型:寻找跨学科共性...

来源:人工智能AI技术 论文虽然有些难懂,但或许是一个新的研究方向。强化学习和决策多学科(Multi-Disciplinary Conference on Reinforcement Learning and Decision Making, RLDM)的重要前提是,随着时间的推移&#xf…

IO模型(epoll)--详解-01

写在前面 从事服务端开发,少不了要接触网络编程。epoll作为linux下高性能网络服务器的必备技术至关重要,nginx、redis、skynet和大部分游戏服务器都使用到这一多路复用技术。 本文会从网卡接收数据的流程讲起,串联起CPU中断、操作系统进程调度…

一文搞懂MEMS传感器产业链(最全解析!)

来源:传感器专家网本文涵盖了MEMS产业链的所有与流程与知识,力求用最简短的内容——全文不足8000字,让我们知道最全面的MEMS产业链情况,包括如下内容:一、MEMS简介二、MEMS分类三、MEMS 行业发展历程四、国内传感器企业…

IO模型(epoll)--详解-02

写在前面 从事服务端开发,少不了要接触网络编程。epoll作为linux下高性能网络服务器的必备技术至关重要,大部分游戏服务器都使用到这一多路复用技术。文章核心思想是:要让读者清晰明白EPOLL为什么性能好。 四、内核接收网络数据全过程 这一步…

MIT设计深度学习框架登Nature封面,预测非编码区DNA突变

来源:ScienceAI作者:Raleigh McElvery编辑:小舟、张倩来自 MIT 和哈佛大学博德研究所等机构的一项研究刚刚登上了 Nature 封面。他们创建了一个数学框架来预测基因组中非编码序列的突变及其对基因表达的影响。研究人员将能够利用这些模型来设…

IO模型(epoll)--详解-03

写在前面 epoll是开发linux高性能服务器的必备技术至,epoll本质,是服务端程序员的必须掌握的知识。 七、epoll的原理和流程 本节会以示例和图表来讲解epoll的原理和流程。 创建epoll对象 如下图所示,当某个进程调用epoll_create方法时&#x…

机器学习重新构想计算的构建块

来源:ScienceAI编辑:绿萝传统算法为机器学习等复杂的计算工具提供动力。一种称为「预测算法」的新方法利用机器学习的力量来改进算法。算法——允许程序对数据进行排序、过滤和组合等的代码块——是现代计算的标准工具。就像手表里的小齿轮一样&#xff…

js实现模糊查询

1、使用indexOf 2、使用match 3、使用test 4、使用stringObject.split(),字符串分割方法&#xff0c;如果字符串可以被分割说明含有这个字符串 <html><head><title>test</title></head><body><input type"text" id"btn&…

丘成桐谈几何:从黎曼、爱因斯坦到弦论

来源 &#xff1a; 超级数学建模著名数学家丘成桐先生发表了题为“几何&#xff1a;从黎曼、爱因斯坦到弦论”的演讲&#xff0c;追溯了为广义相对论发展奠定基础的的黎曼几何&#xff0c;回顾了影响广义相对论发展的物理学突破&#xff0c;并谈及量子力学和引力理论相结合、引…

图卷积网络的五年

来源&#xff1a;ScienceAI作者&#xff1a;Mostafa Haghir Chehreghani编辑&#xff1a;萝卜皮图卷积网络&#xff08;Graph Convolutional Networks&#xff0c;GCN&#xff09;已成为使用图和网络进行学习的流行工具。我们应该反思一下成功故事背后的原因。论文链接&#xf…

【前沿技术】“中国天眼”观测到宇宙极端爆炸起源证据

来源&#xff1a;智能研究院据新华网报道&#xff0c;我国科研团队通过“中国天眼”FAST观察并计算出快速射电暴的起源证据&#xff0c;这一发现于18日刊登于国际权威学术期刊《科学》杂志。中国科学院国家天文台研究员、“中国天眼”首席科学家李菂介绍&#xff0c;快速射电暴…

红黑树存在的合理性

写在前面 主要描述为什么有了二叉查找树/平衡树还需要红黑树 1、二叉查找树的缺点 二叉查找树&#xff0c;相信大家都接触过&#xff0c;二叉查找树的特点就是左子树的节点值比父亲节点小&#xff0c;而右子树的节点值比父亲节点大&#xff0c;如图 基于二叉查找树的这种特点&a…

认清智能化战争的制胜根本

来源&#xff1a;中国军网作者&#xff1a;石海明、裴帅在战争领域&#xff0c;如果说有什么是亘古不变的真理&#xff0c;那就是“变化”。伴随着前沿智能科技的飞速发展&#xff0c;智能化时代扑面而来&#xff0c;智能化战争也初露端倪&#xff0c;冲击着人们对战争的原有认…

DeepMind的AI能指导人类的直觉吗?

来源&#xff1a;AI前线作者&#xff1a;Ben Dickson译者&#xff1a;Sambodhi策划&#xff1a;凌敏DeepMind 研究人员最近发表了一篇题为《通过用人工智能引导人类直觉来推进数学》&#xff08;Advancing mathematics by guiding human intuition with AI&#xff09;的论文&a…

NoSQL那些事--Redis

Redis是个流行的内存数据库(in-momery)。接口好用&#xff0c;性能也很强&#xff0c;还支持多种数据结构&#xff0c;加上各种高可用性集群方案&#xff0c;实在是太太太好用了。 但是就是因为太好用了&#xff0c;好用到让很多人都晕了脑子&#xff1a; 用Redis性能就大大提高…

柳昀哲课题组在Nature Reviews Neuroscience上发表长篇综述提出表征富集理论

来源&#xff1a;北师大脑与认知科学“读心解梦”一直以来是人们追求的梦想&#xff0c;从佛洛依德对于潜意识意义的追寻&#xff0c;到当今神经科学的神经信号解码&#xff0c;人们采用主观或客观的方式理解人类高级智能的脚步从未停止。早期人们理解人类意识的内涵&#xff0…

Excel生成Sql语句 格式如:=字符串1A2字符串2C2字符串3

我们有时候需要根据Excel生成sql语句&#xff0c;可以利用Excel的字符串拼接&。格式如&#xff1a;"字符串1"&A2&"字符串2"&C2&"字符串3" 例如&#xff1a;在一个Excel中&#xff0c;我们要在Data_Company表中&#xff0c;根…