GO scheduler
2023-10-09 21:15:59   25  举报             
     
         
 AI智能生成
  Go 调度相关硬核知识
    作者其他创作
 大纲/内容
  监控线程    
     sysmon 的启动  
     sysmon作用    
     GC    
     通知GC:垃圾回收器超过2分钟没有执行的话,sysmon 监控线程也会强制进行GC。  
     归还内存:每5分钟归还GC后不再使用的span给操作系统(scavenge)
  
     保证timer 运行,查看应该在运行却仍在等待执行的计时器timer,尽可能快地运行它们.    
     打印调度信息  
     监控 netpoller ,定时从 netpoller 中获取 ready 的协程,放入 GRQ
  
     Preemption:执行抢占    
     监控系统调用:将 P 与 M 脱离  
     非系统调用,通知抢占  
     执行    
     其周期 (循环时间) 是动态的,取决于正在运行的程序的当前活动。  
     不运行,进入休眠
    
     垃圾回收器即将要运行. (sysmon线程将在垃圾回收结束时恢复)  
     所有线程都处于空闲状态,没有任何一个在运行中  
     G 抢占    
     提问    
     goroutine没有优先级么?是的  
     什么时候需要抢占?  
     如何抢占,新老抢占的实现有何不同?  
     抢占的触发时机    
      GC STW  
     栈扫描  
     监控线程 sysmon 触发  
     抢占的实现    
     老版本-协作式抢占    
     preemptone 函数只做标记⼯作
  
     检查当前栈空间是否⾜够,不够的话,需要申请新的栈空间  
     保存当前goroutine的运⾏现场,切换到m.g0,执⾏newstack  
     gopreempt_m将当前的goroutine放进了全局队列  
     新版本 - 信号式抢占    
     preemptone 函数:通过系统调⽤ tgkill 函数,给特定的线程发信号  
     处理 SIGURG 信号时,相当于被强⾏插⼊⼀条 asyncPreempt 的函数调⽤  
     推荐    
     曹大 抢占调度PPT  
     曹大 抢占调度  
     实际应用    
     为什么Go服务容器化之后延迟变高?    
     原因:Go服务容器化的 P 数量问题  
     解决方案:引入 uber 的 automaxprocs 库  
     Go服务最好不要用太多的CPU  
     参考资料    
     Golden Go调度篇  
     深入浅出GolangRuntime  
     为什么Go服务容器化之后延迟变高  
     Go 为什么这么“快”
  
     Golang 的 goroutine 是如何实现的?
  
     Golang sysmon监控线程  
     引言    
     什么是调度?    
     运行&阻塞  
     演化:Process -> Thread(LWP, lightweight process) -> Goroutine (一种lightweight userspace thread) =》一个不断共享、不断减少切换成本的过程.  
     思考问题    
     怎样实现少量内核线程支撑大量 Goroutine 的并发运行?  
     为什么说Go调度Goroutine是轻量的?    
     上下文切换代价小  
     内存占用少  
     调度模型    
     基本概念
    
     G:goroutine 一个计算任务  
     M: machine 系统线程  
     P: processor 虚拟处理器  
     GM模型(go 1.0)    
     全局调度锁问题  
     G 的传递问题  
     Per-M 的内存问题  
     GMP 模型(go 1.0 +)    
     交互形式    
     简图    
     源码 1  
     源码 2  
     详情  
     全景大图  
     G状态流转    
     G 状态列表  
     G 状态流转图  
     举例说明  
     调度器    
     调度循环(Schedule loop)    
     M 执行 G 时四个方法周而复始  
     队列优先级: runnext  > local run queue > global run queue > other p local run queue  
     调度策略    
     hand off 机制: 当本线程因为 G 进行系统调用阻塞时,线程释放绑定的 P,把 P 转移给其他空闲的线程执行。  
     work-stealing 机制:当本线程无可运行的 G 时,尝试从其他线程绑定的 P 偷取 G,而不是销毁线程  
     调度过程  
     调度时机  
     调度优化    
     提问 🙋    
     为了最大限度利用计算资源,Go 调度器是如何处理线程阻塞的场景?  
     原子、互斥量(锁)、通道操作:切换阻塞 G  
     网络 IO 请求:让 netpoll 去处理,切换阻塞 G    
     step 1  
     step 2  
     step 3  
     网络轮询器 netpoller            
     syscall 调用:监控线程 sysmon 会监控识别,将 P 与 M 脱离,让 P 与其他空闲M结合    
     step 1  
     step2  
     step 3  
     sleep 操作:监控线程 sysmon,会监控那些长时间运行的 G 任务,会进行抢占操作  
    
 
 
 
 
  0 条评论
 下一页
 为你推荐
 查看更多
    
   
   
   
   
   
  
  
  
  
  
  
  
  
  
  
 