go的调度
操作系统根据资源访问权限的不同,体系架构可以分为用户空间和内核空间;内核空间主要操作访问CPU资源,IO资源,内存资源等硬件资源,为应用程序提供最基本的基础资源;用户空间是上层应用程序的固定活动空间,用户空间不能直接访问内核空间,必须通过系统调用,库函数或者shell脚本来调用内核空间提供的资源。
线程模型的实现,可以分为以下几种方式:
1. 用户级线程模式
用户线程和内核线程KSE是 N:1 模型,N个用户空间线程在1个内核空间线程上运行,程序线程的创建、切换、同步、终止等线程工作必须自身来完成,无需借用系统调用来实现。一个进程中所有创建的线程都只和同一个KSE在运行时动态绑定,也就是说,操作系统只知道用户进程而对其中的线程是无感知的,内核所有的调度都基于用户进程。由于线程调度是在用户层面完成,不需要CPU在用户态和内核态切换;因此他的优势是上下文切换非常快,缺点是无法利用多核系统的优点。
2. 内核级线程模型
用户线程和内核线程KSE是 1:1 的模型,也就是每一个用户线程都绑定一个内核线程,而线程的调度都交给内核去做,应用程序对线程的创建、终止、同步等调度工作都是基于内核提供的系统调用来完成。这种模型的优势是实现简单,直接借助了操作系统内核的线程已经调度器,所以CPU可以快速切换调度线程,于是多个线程可以同时运行;缺点是由于借助了内核来完成线程的创建、销毁和线程之间的上下文切换和调度,因此资源成本大幅上涨,对性能影响很大。
3. 两级线程模型
用户线程和内核线程KSE是M:N的模型,两级线程模型中的一个进程可以与多个内核线程KSE相关联,于是进程中不同的线程可以绑定不同的KSE, 这点和内核级线程模型相似;其次,又区别于内核线程,他的进程中线程不是与KSE一一绑定,而是动态的绑定一个KSE;当某个KSE因为其绑定的线程的阻塞操作被内核调度出CPU时,其关联进程中的其余用户线程可以重新与其他KSE相绑定运行。所以,两级线程模型既不是用户级线程模型那种完全靠自身调度的模型也不是内核级线程模型那种完全靠操作系统调度的;go的两级模型即用户调度器实现用户线程到KSE的调度,内核调度器实现KSE到CPU的调度。
G-P-M模型
任何用户线程最终肯定要交由OS线程来执行,goruntine(G) 也同样,但是G并不直接交由OS线程运行,而是由 P - 逻辑处理器来作为两者之间的中介来运行。P可以看作一个抽象的资源或上下文,一个 P 绑定一个OS线程,在go中,把OS线程抽象为一个 M;G实际是由M通过P来调度运行的,但是对于G而言,P提供了G运行所需的一切资源和环境,在G看来,P就是CPU。由G\P\M这三种抽象出来的实现,最终形成了
GO调度器的基本结构:
G:表示 goruntine, 每个goruntine对应一个G的结构体,G存储goruntine的运行堆栈,状态及任务函数,可重用;每个G要被绑定到P上才能调度执行。
P:表示逻辑处理器,对每个G来说,P相当于CPU核,G只有被绑定到P上才能被调度。对M来说,P提供了相关的执行环境(context),如内存分配状态,任务队列等。
M:OS线程抽象,代表着真正执行计算的资源,在绑定了有效的P后,进入schedule循环;schedule循环的机制大致是从Global队列,P的local队列以及wait队列中获取到G, 切换到G的执行栈上并执行G的函数,调用 goexit做清理工作并回到M,如此循环。
G-P-M模型调度
Go调度器工作时会维护两种用于保存G的任务队列:一种是一个Global任务队列,一种是每一个P维护的任务队列。
当通过go关键字创建一个新的goruntine时,他会优先放入P的本地队列,当P本地队列满了,会把本地队列的一半送给全局队列。为了运行goruntine, M需要绑定一个P, 接着 M会启动一个 OS线程,循环从 P的本地队列中取出一个goruntine并执行。当M执行完当前P的local队列中所有的G后,会从global 队列中寻找G来执行【将全局G个数/P个数转移到本地队列】,如果global队列为空,他会随机挑选一个P,从中取出一半G到自己的队列中执行。
转自:https://www.cnblogs.com/williamjie/p/9267741.html
go的调度的更多相关文章
- 大数据之Yarn——Capacity调度器概念以及配置
试想一下,你现在所在的公司有一个hadoop的集群.但是A项目组经常做一些定时的BI报表,B项目组则经常使用一些软件做一些临时需求.那么他们肯定会遇到同时提交任务的场景,这个时候到底如何分配资源满足这 ...
- [Quartz笔记]玩转定时调度
简介 Quartz是什么? Quartz是一个特性丰富的.开源的作业调度框架.它可以集成到任何Java应用. 使用它,你可以非常轻松的实现定时任务的调度执行. Quartz的应用场景 场景1:提醒和告 ...
- [Spring]支持注解的Spring调度器
概述 如果想在Spring中使用任务调度功能,除了集成调度框架Quartz这种方式,也可以使用Spring自己的调度任务框架. 使用Spring的调度框架,优点是:支持注解(@Scheduler),可 ...
- Quartz.net 开源job调度框架(二)----定点执行
在上一篇 Quartz.net 开源job调度框架(一) 中讲到了基本的使用以及配置job轮训数据执行 这种做法适用于对数据操作实时性要求不高的场景,在实际场景中还有一种比较常用的场景就是我们需要在 ...
- Quartz.NET总结(四)Quartz 远程调度
前面篇已经介绍了Quartz.NET的配置,使用和Cron表达式表达式的写法.基本上后台的定时任务的定时执行已经完成,并能正确的按照执行计划,执行相关的job . 然后,如果任务需要更新,停止某个任务 ...
- 【Java EE 学习 77 上】【数据采集系统第九天】【通过AOP实现日志管理】【通过Spring石英调度动态生成日志表】【日志分表和查询】
一.需求分析 日志数据在很多行业中都是非常敏感的数据,它们不能删除只能保存和查看,这样日志表就会越来越大,我们不可能永远让它无限制的增长下去,必须采取一种手段将数据分散开来.假设现在整个数据库需要保存 ...
- Quartz定时调度框架
Quartz定时调度框架CronTrigger时间配置格式说明 CronTrigger时间格式配置说明 CronTrigger配置格式: 格式: [秒] [分] [小时] [日] [月] [周] [年 ...
- #研发解决方案#分布式并行计算调度和管理系统Summoner
郑昀 创建于2015/11/10 最后更新于2015/11/12 关键词:佣金计算.定时任务.数据抽取.数据清洗.数据计算.Java.Redis.MySQL.Zookeeper.azkaban2.oo ...
- 掌握 cinder-scheduler 调度逻辑 - 每天5分钟玩转 OpenStack(48)
上一节我们详细讨论了 cinder-api 和 cinder-volume,今天讨论另一个重要的 Cinder 组件 cinder-scheduler. 创建 Volume 时,cinder-sche ...
- 编写简单的ramdisk(选择IO调度器)
前言 目前linux中包含anticipatory.cfq.deadline和noop这4个I/O调度器.2.6.18之前的linux默认使用anticipatory,而之后的默认使用cfq.我们在前 ...
随机推荐
- 配置 PackMan 镜像
一.参考链接 阿里云镜像站 二.PackMan 镜像介绍 Packman 是 OpenSUSE 最大的第三方软件源,主要为 OpenSUSE 提供额外的软件包,包括音视频解码器.多媒体应用.游戏等. ...
- 采用二进制文件方式安装loki和promtail
1. 下载二进制文件 官方下载地址:https://github.com/grafana/loki/releases 下载如图所示的这俩文件,Grafana采用yum方式安装 cd /usr/loca ...
- 6月4日 python学习总结 初次接触jQuery
1. jQuery是什么?是一个轻量级的,兼容多浏览器的JS库(write less, do more) 1. 是一个工具,简单方便的实现一些DOM操作 2. 不用jQuery完全可以,但是不明智. ...
- Badger简单使用
Badger简介 badger 是 dgraph 开源的 LSMTree 的 KV 引擎,它相比 leveldb 有 KV 分离.事务.并发合并等增强,是 go 生态中比较生产级的存储引擎了. 文档: ...
- Android BLE 蓝牙开发——扫码枪基于BLESSED
一.蓝牙模式HID与BLE 当扫码枪与手机连接时,通常采用的是蓝牙HID(Human Interface Device)模式.本质上是一个把扫码枪作为一个硬件键盘,按照键盘协议把扫码后的结果逐个输入到 ...
- Blazor 003 : Razor的基础语法
上文,我们通过剖析一个最简单的 Blazor WASM 项目,讲明白了 Razor 文件是什么,以及它被转译成 C#后长什么样子.也介绍了 Razor 中最简单的一个语法:Razor Expressi ...
- vue异步组件?
为了简化,Vue 允许你以一个工厂函数的方式定义你的组件,这个工厂函数会异步解析你的组件定义.Vue 只有在这个组件需要被渲染的时候才会触发该工厂函数,且会把结果缓存起来供未来重渲染Vue.compo ...
- 在 Java 中 CycliBarriar 和 CountdownLatch 有什么区别?
CyclicBarrier 可以重复使用,而 CountdownLatch 不能重复使用. Java 的 concurrent 包里面的 CountDownLatch 其实可以把它看作一个计数器, 只 ...
- Oacle 插入多条记录的语法理解;INSERT ALL INTO ....... SELECT 1 FROM dual;
单表Insert into的语句就不说了,这里主要说插入多条语句的说明 For a multitable insert operation, each expression in the values ...
- 实践中如何优化 MySQL ?
最好是按照以下顺序优化: 1.SQL 语句及索引的优化 2.数据库表结构的优化 3.系统配置的优化 4.硬件的优化 详细可以查看 阿里 P8 架构师谈:MySQL 慢查询优化.索引优化.以及表等优化