说说wakep和m的创建吧

wakep调用时机和作用

  • 作用:wakep的作用是添加一个P来执行goroutinue
  • 时机:在有G变为runnable的时候 如:newproc ready
    wakep中调用startm来启动一个新的m

startm

  • 首先如果传递过来P是nil,则需要获取一个idle P,如果获取不到,直接返回
  • 调用mget获得一个已经睡眠m
  • 如果没有获得m,则调用newm创建一个新的m
  • 如果是创建的m则直接返回,后面再具体将newm的功能。如果是获取的m,则调用notewakeup来唤醒m(因为m在mput的时候已经睡眠了)

mget

mget比较简单,就是从midle中取出一个通过mput放入的m,如果没有则返回nil

newm

func newm(fn func(), _p_ *p)

先看看注释:

// Create a new m. It will start off with a call to fn, or else the scheduler.
// fn needs to be static and not a heap allocated closure.
// May run with m.p==nil, so write barriers are not allowed.

创建一个m并执行fn或者是一次调度,所谓创建m就是启动一个系统线程。

  • 调用allocm创建一个m并设置m.nextp为传进来的参数_p_,allocm还为m创建g0,并设置一个栈
  • 这里有cgo的东西,暂时先不说,我也不懂,呵呵。
  • 如果不是cgo,调用newosproc

newosproc

这个函数就有点系统相关了,这里看os_windows.go下的。
这个函数会调用一个系统调用来创建线程
这里创建的线程的启动函数为tstart_stdcall

所以我们先不纠结系统调用的问题,直接看线程启动之后会干嘛:

这个函数是用汇编写的(sys_windows_amd64.s)

在这个函数中,第一参数是存放在CX中。参数就是前面创建的m

  • 获取g0
  • 在这个函数中会重新设置栈给g0
  • 这里把当前线程的栈顶给g的栈底,然后预留64K的空间给g0,并设置栈的stack_hi和stack_lo,以及stackguard0和stackguard1.
  • 设置线程本地存储 将m的tls设置到0x28(GS),然后设置m给g0.m,设置g0给tls,以便g(tls)可以取到当前g。
  • 调用runtime.stackcheck
  • 调用runtime.mstart

stackcheck就是检查当前的SP是不是[stack_hi,stack_lo)区间
然后看mstart

mstart

这里lo != 0, ==0那一段代码得意思就是在这里设置设置栈
意思是说cgo的时候可能值设置了栈大小到stack.hi
所以这里先创建一个局部变量size保存stack.hi,因为size是局部变量,所以就把size的栈地址设置为stack.hi,然后根据size计算出stack.lo

调用mstart1

mstart1会进行一些初始化并保存g0的栈等,

如果这里是m0,还会初始化信号量等。

如果m有startfn这个函数,也就是之前调用newm的时候传递了函数过来的话,就先执行这个函数。sysmon就是通过这种方式执行的。

这里如果是helpgc,则直接停掉这个m,或者如果不是m0,会把m.nextp设置给m.p

然后调用schedule来调度任务。

schedule

这个函数主要是找到一个runnable的g 然后调用execute来启动g

  • 这里有可能会只是trance或者gc的g,这部分还不太了解。

  • 下面是先从全局队列里面取一次,因为如果不先取全局队列,那么有可能两个g互相继续而导致全局的g没有机会运行。

  • 然后尝试从本地(P)的队列获取一个g

  • 调用findrunnable,这个函数会阻塞知道找到一个可运行的g

  • 如果找到一个g且为m为spinning,则清除状态

  • 调用execute执行找到的g

findrunnable

  • 如果gcwatting stopm
  • fingwait没看懂
  • 从本地P队列获取g
  • 从全局队列获取g
  • 如果没有人在进行netpoll,尝试netpoll发现g
  • 如果当前所有的P都是idle状态, 跳过从别的P偷取工作流的流程,否则进行偷取
  • 如果spinning的M大于busy的P,则直接让m睡眠
  • 又是GC的worker
  • 设置P为idle
  • 暂时让nmspinning-1,然后再次检查所有P上的runq,发现有P上有多余的goroutinue,则让M重新得到一个P,然后再次进行上面的查找g的流程。
  • 又是GC
  • 如果没有人在netpool,让当前M永久阻塞在netpool睡眠。
  • 如果有人在netpool了,则直接stopm,让m睡眠

execute

  • 先把g的状态设置为running
  • 设置栈为正常状态而不是preempt状态
  • 调用gogo切换SP和PC等。

golang 调度之wakep和M创建相关推荐

  1. Golang调度器GPM原理与调度全分析

    第一章 Golang调度器的由来 第二章 Goroutine调度器的GMP模型及设计思想 第三章 Goroutine调度场景过程全图文解析 一.Golang"调度器"的由来? (1 ...

  2. 开源分布式Job系统,调度与业务分离-如何创建一个计划HttpJob任务

    项目介绍: Hangfire:是一个开源的job调度系统,支持分布式JOB!! Hangfire.HttpJob 是我针对Hangfire开发的一个组件,该组件和Hangfire本身是独立的.可以独立 ...

  3. 从Golang调度器的作者视角探究其设计之道!

    导语 | Golang核心开发人员.goroutine调度的设计者Dmitry Vyukov,在2019年的一个talk里深入浅出地阐述了goroutine调度的设计思想以及一些优化的细节.本文是笔者 ...

  4. golang调度模型

    https://tonybai.com/2017/06/2... 线程模型 内核级线程模型(KSE(Kernel Scheduling Entity)) 关键点: 完全靠操作系统调度 每一个用户线程绑 ...

  5. golang 初始化并赋值_Go语言创建、初始化数组的常见方式汇总

    本文实例总结了Go语言创建.初始化数组的常见方式.分享给大家供大家参考.具体分析如下: Go语言的语法很灵活,以下展示了创建并初始化数组的多种方式: //数组初始化的各种方式 func arraySl ...

  6. golang对mongo数据库索引的创建,删除操作

    package main import (     "fmt"     "log"     "time" "gopkg.in/mg ...

  7. 组件分享之后端组件——阿里妈妈前端团队出品的开源接口管理工具RAP第二代rap2-delos...

    组件分享之后端组件--阿里妈妈前端团队出品的开源接口管理工具RAP第二代rap2-delos 背景 近期正在探索前端.后端.系统端各类常用组件与工具,对其一些常见的组件进行再次整理一下,形成标准化组件 ...

  8. golang源码分析:调度器chan调度

    golang调度机制chan调度 golang的调度策略中,碰见阻塞chan就会将该chan放入到阻塞的g中,然后再等待该chan被唤醒,这是golang调度器策略的主动调度策略之一,其中还有其他的主 ...

  9. Golang知识点二、GMP调度模型

    GMP调度模型 1. 调度器由来   调度器分为进程调度器和线程调度器. 1.1. 单进程时代   单进程系统存在一定问题:1. 单一执行流程.计算机只能一个任务一个任务处理 2. 进程阻塞所带来的C ...

最新文章

  1. 成功检测远距离目标,将点云与RGB图像结合,谷歌Waymo提出新算法:4D-Net
  2. python期末知识点总结_期末考试必备复习提纲丨9年级数学上册知识点总结归纳(人教版)...
  3. C# 笔记 .net与C#简单说明
  4. 信号分解:双正交、完备性、对偶向量
  5. [j2me]手机也可以玩播客(Podcast)! Geek开发说明[开源]
  6. CSS魔法堂:那个被我们忽略的outline 1
  7. GNU开发工具——Bochs模拟器
  8. ctf攻防渗透-加密-栅栏密码
  9. 数据库中常见mdf 、ndf 、ldf 、文件
  10. Shopee优选卖家真的重要吗?
  11. 腾讯回应“暴力裁员”
  12. 计算机路由器无线级联配置,两个无线路由器级联怎么设置?
  13. 安卓眼球追踪_一问易答:非三星手机如何实现眼球追踪
  14. 解救IP被封的服务器
  15. php 调用 C++
  16. 掘金 AMA:听闲鱼客户端架构师--邬吉风聊 Flutter 和移动端开发那些事
  17. NSPredicate模糊、精确、查询
  18. 通用权限管理设计篇_设计模式
  19. 将localhost换成自己电脑的ip的方法
  20. Ubuntu笔记本 在终端 听 收音机

热门文章

  1. 徐明星系列之徐明星创办的OK资本成为RnF金融有限公司的锚定投资者
  2. linux configure 的 --prefix 参数的作用
  3. underscore.js 报_is not defined解决方法
  4. vb实现webbrowser显示html,VB.NET 通过窗口句柄,获取webbrowser控件HTML内容
  5. 归并排序算法(C语言)
  6. 01背包总结+传授个人经验
  7. 安装docker和docker的开机启动及容器的开机自启
  8. Linux学习日记15——exec函数族、回收子进程
  9. [停更] 微信平台上的DRL [停更]
  10. linux下怎样安装openmpi