纯净、安全、绿色的下载网站

首页|软件分类|下载排行|最新软件|IT学院

当前位置:首页IT学院IT技术

Go goroutine模型与调度策略 Go并发的方法之goroutine模型与调度策略

朱骥伦   2021-11-17 我要评论
想了解Go并发的方法之goroutine模型与调度策略的相关内容吗朱骥伦在本文为您仔细讲解Go goroutine模型与调度策略的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Go,goroutine模型与调度策略,Go,并发调度策略下面大家一起来学习吧。

学习刘丹冰《8小时转职golang工程师》本节都是原理

单进程操作系统

早期的单进程操作系统可以理解为只有一个时间轴CPU顺序执行每一个进程/线程这种顺序执行的方式CPU同一时间智能处理一个指令一个任务一个任务去处理

这样就会导致进程阻塞的话CPU就会卡在当前进程一直在等待CPU就会浪费

多线程/多进程操作系统

CPU利用轮询机制调度各个进程每个进程都分配固定的时间片这个时间片很小先执行进程A如果A结束了那没问题切换到下一进程B但如果时间片内A没结束CPU不管A没结束会强制切换到下一进程B以此类推CPU就避免了阻塞在某一进程

但这样的问题是在频繁切换进程的过程中进程的切换就必然会导致切换成本例如保存当前线程状态系统调用环境的上下文切换各种拷贝复制就会导致时间浪费大部分时间都用在切换了进程数量越多切换的浪费就越大

因此软件的目标就是提高CPU利用率

另一方面进程的内存占用也是很大的问题

1:N模型

程序员的任务就是在用户态调接口开发业务内核态负责调硬件调系统资源用户线程和内核线程一一绑定CPU只需要管内核线程这样的内核线程称为thread用户线程称为co-routinethread通过管理协程调度器管理多个协程这样CPU还是只管理一个线程

在这里插入图片描述

这样就在用户态实现了并发CPU也不用切换了只用在协程切换时消耗很少的资源解决了CPU高消耗调度的问题

这样的弊端是有一个协程阻塞了下一个协程就不能执行了

M:N模型

M个线程通过协程调度器管理多个协程CPU的调度优化我们没法做这个协程调度器就非常重要了

goroutine

在go中协程co-routine被改为goroutine一个goroutine只占几kb因此可以有大量的goroutine存在另一方面goroutine 的调度器非常灵活

goroutine早期调度器

早期的goroutine调度器有一个全局的goroutine队列这个队列有一个锁每个线程要创建、销毁、运行一个goroutine都要先获取一个锁然后执行goroutine执行完毕后再把锁还回去

这样的问题是激烈的锁竞争

另一方面当一个线程执行一个goroutine时这个goroutine新创建了一个goroutine为了保证并发这个新goroutine肯定得执行这个新创建的就被放在下一个线程去执行这实际上不满足程序的局部性原理

另外系统在频繁调用不同的线程还是会造成系统开销

GMP

在操作系统中有一个操作系统调度器用来调度CPU来处理不同的内核线程在这之上每个线程有一个处理器这个处理器里有goroutine的各种资源堆、栈、数据等这样的处理器称为P每个P管理一个自己的本地队列这个队列里存放着这个P要处理的goroutinegoroutine要被处理时线程获取一个PP调度出一个goroutine交给线程线程对goroutine进行处理除了P的本地队列外还有一个全局队列里面也存放着要运行的goroutine

在这里插入图片描述

调度器设计策略

 复用线程

work stealing

当一个线程正在执行一个goroutine时并且它的P本地队列里还有待执行的goroutine别的P空闲的话就会帮它的线程偷取一个goroutine

在这里插入图片描述

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

在这里插入图片描述

hand off

如果说一个P正执行的goroutine突然阻塞了比如在等待输入之类的那么这时候这个P的线程也就是这个CPU实际上没有被利用这时候就会创建/唤醒一个新的线程这时候让阻塞的goroutine继续阻塞当前CPU变为睡眠状态但把物理CPU切换走到不阻塞的线程上其余的P和P的本地队列直接被转移到新的线程上控制如果之前的阻塞routine又不阻塞了那把这个goroutine又加入到别的队列后
在这里插入图片描述

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

在这里插入图片描述

并行

P的数量可以宏定义例如为CPU核心数/2

抢占

在1:1模型中一个协程和一个线程绑定当有别的协程需要运行时当前的协程除非释放出这个线程资源否则新来的就只能等着

而goroutine的机制是每个goroutine只有10ms时间用完后新的goroutine一定会抢占这个CPU没有谁优先大家都很平均

全局队列

在这里插入图片描述

一个线程如果没有要执行的goroutine根据work stealing去别的本地队列偷如果别的队列也没得偷就去全局队列里拿全局队列里别的goroutine前移


相关文章

猜您喜欢

  • C++构造函数 详解C++构造函数

    想了解详解C++构造函数的相关内容吗weixin_46369425在本文为您仔细讲解C++构造函数的相关知识和一些Code实例欢迎阅读和指正我们先划重点:C++详解,C++构造函数下面大家一起来学习吧。..
  • Python 修改游戏 Python修改游戏内存的方法

    想了解Python修改游戏内存的方法的相关内容吗落伍的码农在本文为您仔细讲解Python 修改游戏的相关知识和一些Code实例欢迎阅读和指正我们先划重点:Python,修改游戏,Python,修改游戏内存下面大家一起来学习吧。..

网友评论

Copyright 2020 www.tdogsoftware.com 【零度软件园】 版权所有 软件发布

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 点此查看联系方式