1.概述
golang本质就是GPM三个实体实现的调度。
G对应每个任务,P对应每个processor概念(就是会包含一堆的G,比如先执行G1,在执行G2)M对应系统线程,M(还包含系统栈之类的概念)绑定一个P之后就开始逐个运行P里面的G。

最基本的流程图就是雨痕给的

后面雨痕对于GPM三者的解释也很到位。我这里不抄袭了。

2.初始化
首先介绍的就是schedinit()里面主要是procresize函数。

这个procresize()就是调整系统里面P的数量。一般就是系统的cpu内核的数量,初始化时也实行多退少补的原则,只是退的时候要注意是否退出的P包含了当前P,如果是就需要一大堆的细节上的处理。

这里还有个所有P的管理结构

var allp [_MaxGomaxprocs + 1]*ptype schedt struct {pidle puintptr //  P  npidle uint32 //  P
}

还有个提示,如果调用手动调用并修改runtime.GOMAXPROCS就会引发stopTheWorld以及startTheWorld,这两个动作本身是比较好耗时的,之后在startTheWorld执行的procresize()也是比较耗时的。

3.任务 G/P
先举了个栗子,通过

go build -o test test.gogo tool objdump -s "main\.main" testgo add(x, y)会被汇编成类似CALL runtime.newproc(SB)
这种代码

然后就去runtime找了。

newproc(获取pc/ip地址以及入参等重要信息后)->newproc1

之后登场的G的数据结构

type g struct {stack stack  //执行栈sched gobuf  //用于保存执行现场goid  int64  //唯一序号gopc  uintptr //调用者 PC/IPstartpc uintptr //任务函数
}

newproc1一开始就处理各种处理创建G,测试G,对齐地址,拷贝栈,保存现场的各种杂活儿。然后一个runqput(p, newg, true),被put进去了。

runqput有可能把g作为P.runnext,也可能放在末尾,也有可能丢到全局队列。

稍微介绍了g通过p然后进行二级缓存复用的逻辑,类似cache/object,central的做法。分别对应gfget, gfput两个函数。
所有的g 还有个全局应用allgs/allg,用来索引所有的G方便回收和shrinkstack。

补充了个细节只有本地的P队列堆满了才会丢到全局队列,而且一次会丢本地队列长度的一半,保证效率和多核均匀调度。

4.线程 M
当结束runqput之后,开始wakep了,
wake->startm->newm创建/或者notewakeup(&mp.park)

newm->newosproc->linux调用

clone(cloneFlags,stk,unsafe.Pointer(mp),unsafe.Pointer(mp.g0),unsafe.Pointer(funcPC(mstart))) 开启系统线程,并且入口函数是mstart
所有m会被添加到allm链表,不会被释放,超过10000崩溃。

最后补充了两个细节1:m也是有复用的,mput&mget使用1级缓存。
然后说不要创建太多m啊,time.Sleep比C.sleep(1)要好,之类的。

5.执行
上面说到newm的时候会注册系统线程并把mstart作为入口函数。
然后这里就讲mstart

mstart ->
mstart1 aquirep绑定p ->
schedule()兼顾帮助垃圾回收标记之类的各种杂活,findrunable,->
调用execute->
各种准备好栈JMP入函数入口地址PC->
各种调用结束后RET指令把预先压入的goexit地址恢复到PC/IP->
将G返回服用链表->
重新schedule()

然后介绍了一下findrunable的主干:
1.通过runqget拿本地的P的东西,
2.globrunqget
3.检查netpoll任务
4.尝试偷取其他P的任务。(基于CAS和atomicset弄的Work-Stealing算法)

5.这后还会进行各种尝试,如果实在没有就stopm了。

Lockedg
这是cgo的一个特定调用方式,会把当前的g和m绑定,而且只有在结束调用的时候才会松开。

一个m在调用schedule() 如果发现它是被某个G绑定的则会暂时休息。如果发现自己将要调用的G,是被别的m绑定的,则会将它唤醒,然后自己休眠。
所以每个cgo routine在调用完成之前都会有自己专属的一个G调用。cgo因此会产生大量的m。

6.监控

03.1跟雨痕看go源码- go routine(未完待续)相关推荐

  1. Spring事件机制Event源码解析(未完待续)

    Spring事件机制Event源码解析(未完待续) 监听器: ApplicationEvent事件 ApplicationListener监听器(观察者) ApplicationEventMultic ...

  2. 02.2跟雨痕看go源码- 并发清理与三色标记

    据说这是go优化最狠的地方. http://blog.csdn.net/erlib/article/details/51850912 大意是说twitch.tv觉得一次标记的STW(stop the ...

  3. 02.1跟雨痕看go源码-内存分配(分配回收)

    内存分配和垃圾回收有关,这里我们可以先看一下内存分配. 垃圾回收比较复杂,后面讲. 一开始雨痕大大说了几个基本策略: 每次从操作系统申请一大块内存(比如1MB),以减少系统调用. 将申请到的大块内存按 ...

  4. 【iOS开发】—— SDWebImage源码学习(未完)

    文章目录 什么是SDWebImage? sd_setImageWithURL调用关系 步骤一 步骤三 步骤四 步骤五 步骤六 下载步骤 UIImageView+ WebCache UIView+ We ...

  5. 20种看asp源码的方法及工具

    作者:欧杨飘雪  http://blog.csdn.net/flyingsnowy/ 众所周知windows平台漏洞百出,补丁一个接一个,但总是补也补不净.我把我所知道的20种看asp源码的方法总结了 ...

  6. 一点一点看JDK源码(五)java.util.ArrayList 后篇之forEach

    一点一点看JDK源码(五)java.util.ArrayList 后篇之forEach liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 代 ...

  7. 最近看Kafka源码,着实被它的客户端缓冲池技术优雅到了

    最近看kafka源码,着实被它的客户端缓冲池技术优雅到了.忍不住要写篇文章赞美一下(哈哈). 注:本文用到的源码来自kafka2.2.2版本. 背景 当我们应用程序调用kafka客户端 produce ...

  8. 面试有没有看过spring源码_如何看Spring源码、Java每日六道面试分享,打卡第二天...

    原标题:如何看Spring源码.Java每日六道面试分享,打卡第二天 想要深入的熟悉了解Spring源码,我觉得第一步就是要有一个能跑起来的极尽简单的框架,下面我就教大家搭建一个最简单的Spring框 ...

  9. 一点一点看JDK源码(四)java.util.ArrayList 中篇

    一点一点看JDK源码(四)java.util.ArrayList 中篇 liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 1.综述 在前篇中 ...

最新文章

  1. 50、mysql基于mysql-proxy读写分离实战
  2. j2ee之原生AJAX
  3. NotificationListenerService不能监听到通知
  4. devexpress ajax demo,DevExpress Demo示例展示:多功能站点插件 附在线演示
  5. SPI 接口驱动电路设计
  6. 来自GitHub的Python开源项目,100%可用的12306多功能抢票助手,切勿作为商业用途
  7. 计算机基础知识 SERVER
  8. 华为数通笔记-PPP
  9. 3dmax学习记录(二)
  10. 乐鑫Esp32学习之旅 23 安信可 esp32-a1s 音频开发板移植最新 esp-adf 音频框架,小试牛刀如何实现在线文字转语音播放。
  11. VR头戴显示器对健康有害吗?会引发晕动症、视觉辐辏调节冲突
  12. 攻防世界逆向入门题之open-source
  13. Sigil制作epub,正则表达式的使用
  14. 数据结构(邓俊辉)-[第8章]
  15. 力扣----算法(一)
  16. WordNet 介绍(ICL-PKU)
  17. Unity: How to build and debug external DLLs
  18. 模板类h和cpp分开写问题浅析
  19. 光速读懂ElasticSearch
  20. recipe for target 'CMakeFiles/check' failed

热门文章

  1. python安装0x80072ee7_Win8系统无法打开应用商店且提示“服务器错误”及错误代码0x80072EE7的解决方法...
  2. 驱动开发--字符驱动设备2
  3. Ps 初学者教程「52」如何更改照片中的天空颜色?
  4. vue实现登录、注册、退出、跳转等功能,简单实用
  5. iphone原彩显示对眼睛好吗_iphonexr原彩显示要开吗
  6. 我的世界颜色代码服务器不显示,《我的世界》颜色代码快速指南
  7. WAF绕过“小迪安全课堂笔记”信息收集,漏洞发现,漏洞利用,权限控制
  8. php表白情话,表白情话短句向男生 表白闺蜜的话霸气
  9. 更改ubuntu18.04设置,使 开机小键盘默认打开
  10. (转)Mac OS X 下部分Android手机无法连接adb问题之解决方案