golang中goroutine协程调度器设计策略
goroutine与线程
/* goroutine与线程
1. 可增长的栈
os线程一般都有固定的栈内存,通常为2MB,一个goroutine的在其声明周期开始时只有很小的栈(2KB),
goroutine的栈是不固定的,它可以按需增大或缩小,goroutine的栈大小限制可以达到1GB,虽然极少会用到这么大,
所以在go语言中一次创建十万左右的goroutine也是可以的
2. goroutine的调度
GPM是go语言运行时(runtime)层面的实现,是go语言自己实现的一套调度系统,区别于操作系统调度os线程
// 2.1 G: 很好理解,就是个goroutine的,里面除了存放goroutine信息外,还有与所在P的绑定信息
// 2.2 P: 管理着一组goroutine队列,P里面会存储当前goroutine运行的上下文环境(函数指针、堆栈地址、以及地址边界),
P会对自己管理的goroutine队列做一些调度(比如把占用CPU时间过长的goroutine暂停、运行后续的goroutine等等),
当自己的队列消费完了就去全局队列里去取,如果全局队列里也消费完了就会去其它P的队列里抢任务
// 3. M: (machine) 是go运行时(runtime)对操作系统内核线程的虚拟,M与内核线程一般是一一映射关系,
一个goroutine最终要放到M上执行的
3. G P M 模型之间的关系
P与M也是一一对应的关系,它们的关系是,P管理着一组G挂载在M上运行,当一个G长久阻塞在一个M上时,runtime会新建一个M,
阻塞G所在的P会把其它G挂载在新建的M上,当旧的G阻塞完成或者认为其已经死掉时,挥手旧的M
4. P的个数是通过runtime.GOMAXPROCS设定(最大256个),go1.5版本之后默认为物理线程数,
在并发量大的时候会增加一些P和M,但是不会太多,切换太频繁的话得不偿失
5. 单从线程调度讲,go语言相比于其它语言的优势在于os线程是由os内核来调度的,
goroutine则是由go运行时(runtime)自己的调度器调度的,该调度器使用一个称为m:n调度的技术
(复用/调度m个goroutine到n个os线程),其一大特点是goroutine的调度是在用户态下完成的,
不涉及内核与用户态的频繁切换,包括内存的分配与释放,都是在用户态维护着一块大的内存池,
不直接调用系统的malloc函数(除非内存池需要改变),成本比调度os线程低很多。
另一方面充分利用了多核的硬件资源,近似的把若干goroutine均分在物理线程上,
再加上goroutine本身的超轻量,以上种种保证了go调度的性能
*/









golang中goroutine协程调度器设计策略的更多相关文章
- golang中GPM模型原理与调度器设计策略
一.GMP模型原理first: 1. 全局队列:存放待运行的G2. P的本地队列:同全局队列类似,存放待运行的G,存储的数量有限:256个,当创建新的G'时,G'优先加入到P的本地队列,如果队列已满, ...
- golang中最大协程数的限制(线程)
golang中最大协程数的限制 golang中有最大协程数的限制吗?如果有的话,是通过什么参数控制呢?还是通过每个协程占用的资源计算? 通过channel控制协程数的就忽略吧. 以我的理解,计算机资源 ...
- Golang 入门 : goroutine(协程)
在操作系统中,执行体是个抽象的概念.与之对应的实体有进程.线程以及协程(coroutine).协程也叫轻量级的线程,与传统的进程和线程相比,协程的最大特点是 "轻"!可以轻松创建上 ...
- Golang的goroutine协程和channel通道
一:简介 因为并发程序要考虑很多的细节,以保证对共享变量的正确访问,使得并发编程在很多情况下变得很复杂.但是Go语言在开发并发时,是比较简洁的.它通过channel来传递数据.数据竞争这个问题在gol ...
- golang源码阅读:VictoriaMetrics中的协程优先级的处理方式
在阅读VictoriaMetrics的源码的时候,读到了那么平平无奇的一段: // AddRows adds the given mrs to s. func (s *Storage) AddRows ...
- Kotlin协程解析系列(上):协程调度与挂起
vivo 互联网客户端团队- Ruan Wen 本文是Kotlin协程解析系列文章的开篇,主要介绍Kotlin协程的创建.协程调度与协程挂起相关的内容 一.协程引入 Kotlin 中引入 Corout ...
- Golang 入门系列(六)理解Go中的协程(Goroutine)
前面讲的都是一些Go 语言的基础知识,感兴趣的朋友可以先看看之前的文章.https://www.cnblogs.com/zhangweizhong/category/1275863.html. 今天就 ...
- Golang 协程调度
一.线程模型 N:1模型,N个用户空间线程在1个内核空间线程上运行.优势是上下文切换非常快但是无法利用多核系统的优点. 1:1模型,1个内核空间线程运行一个用户空间线程.这种充分利用了多核系统的优势但 ...
- 在PHP中使用协程实现多任务调度
PHP5.5一个比较好的新功能是加入了对迭代生成器和协程的支持.对于生成器,PHP的文档和各种其他的博客文章已经有了非常详细的讲解.协程相对受到的关注就少了,因为协程虽然有很强大的功能但相对比较复杂, ...
随机推荐
- windows10使用VS(VC++)创建c++多进程命名管道通信
代码可以在 这里 下载 代码主要涉及到: 管道通信 多线程(含临界区) 多进程通信 创建的子进程独立运行 更新日志: 04-12-2020 1. 去除自定义函数返回值,改为int作为函数返回值并增加相 ...
- python学习第三天:python基础(数据类型和变量)
注释 以 # 开头的语句是注释,如,注释不会被编译运行: 格式 当语句以冒号:结尾时,缩进的语句视为代码块.按照约定俗成的管理,应该始终坚持使用4个空格的缩进(在文本编辑器中,需要设置把Tab自动转 ...
- Kernel PCA and De-Noisingin Feature Spaces
目录 引 主要内容 Kernel PCA and De-Noisingin Feature Spaces 引 kernel PCA通过\(k(x,y)\)隐式地将样本由输入空间映射到高维空间\(F\) ...
- Null和空值对于avg计算时产生的影响以及处理
为什么要关注这一块呢:1.面试中可能会有涉及 2.工作中真的也可能会用,既然有可能我也用过,就拿出来跟大家分享一下,上一篇的博文,数据已准备好就不做数据准备的介绍了. step1:select * f ...
- Mysql溯源-任意文件读取👻
Mysql溯源-任意文件读取 前言 读了<MySQL蜜罐获取攻击者微信ID>的文章,文中说明了通过mysql蜜罐读取攻击者微信ID的过程,抱着学习的态度尝试了一下 原理 mysql中有一个 ...
- [opencv]统计每个像素值的数目
int histo[256] = { 0 };//直方图统计每个像素值的数目 int width = img.cols, height = img.rows; int num_of_pixels = ...
- Java程序设计基础笔记 • 【第9章 方法与参数类型】
全部章节 >>>> 本章目录 9.1 有参数有返回值的方法 9.1.1 有参数有返回值的方法的定义和调用 9.1.2 返回值的传递过程 9.1.3 方法返回值的注意事项 9 ...
- 编写Java程序,在电脑硬盘里,查看 f:\text4\name 目录是否存在。
查看本章节 查看作业目录 需求说明: 在电脑硬盘里,查看 f:\text4\name 目录是否存在.如果不存在,则创建该目录:如果存在,则查找 readme.txt文件是否存在.如果 readme.t ...
- Sentry 企业级数据安全解决方案 - Relay 入门
内容整理自官方开发文档 Sentry Relay 通过提供作为应用程序和 sentry.io 之间中间层的独立服务来提供企业级数据安全性. Relay 专门设计用于: 在将个人身份信息 (PII) 发 ...
- SpringCloud创建项目父工程
1.说明 本文详解介绍Spring Cloud项目的父工程创建, 由于Spring Cloud项目下有很多模块组件, 需要先创建一个大的父工程项目, 然后在下面创建各个子工程模块. 2.创建父工程 这 ...