Go 分布式学习利器(17)-- Go并发编程之协程机制:Grountine 原理及使用
文章目录
- 1. Thread VS Groutine
- 2. Groutine 调度原理
- 3. Groutine 示例代码
关于Go的底层实现还需要后续持续研究,文中如有一些原理描述有误,欢迎指证。
1. Thread VS Groutine
这里主要介绍一下Go的并发协程相比于传统的线程 的不同点:
创建时默认的stack大小
JDK5 以后Java thread stack默认大小为1M
C++ 的thread stack 默认大小为8M
Grountine 的 Stack初始化大小为2K所以Grountine 大批量创建的时候速度会更快
和 KSE(Kernel Space Entity即内核线程)的对应关系
Java Thread是1:1
Groutine 是M:N,多对多,如下图。
内核线程是由CPU直接调度,如果一个用户线程对应一个内核线程,调度效率来看肯定是快于多个用户线程对应一个内核线程的。然而,实际的开发环境中一个用户线程对应一个内核线程 在 高并发场景下出现的频繁内核线程上下文切换(保留线程上下文,更新CPU内部各种寄存器)对系统性能的影响占主要部分。而Go语言内部实现的线程调度器提供了多个用户线程和一个内核线程对应,这样在高并发场景能够有效降低线程间切换带来的性能消耗。
当然,如果如果仅仅只有几个或者十几个(小于CPU核数)用户线程的应用可能就体现不出Grountine的优势了。
2. Groutine 调度原理
如下图:
- 编号1: 没有被用户线程使用的内核线程
- 编号2: Go自实现的协程调度器P 对应一个内核线程M0。在该调度器中维护了一个协程队列,一个时刻可以有一个协程正在运行G0,其他的协程在调度队列中等待被执行。
- 编号3: 协程处理器没有正在执行的协程,可以从调度队列中取出一个协程
- 编号4: 协程可以通过系统调用来和内核线程绑定
问题1:如果一个正在运行的G协程将Processor 独占时间较久,导致后续排队的协程一直无法运行,Processor如何处理?
Go 运行之后,后台会维护一个守护线程来进行计数 ,表示一个Processor 完成的协程数量。当一段时间发现这个计数没有更新,会向当前正在执行的协程任务栈插入一个flag,协程运行时遇到非inline函数时会读取到这个标记,会将正在运行的自己中断并插入到等待Processor调度的队尾,Processor此时会继续调度其他的协程进行运行。
问题2: 当一个协程(内核线程的执行)被系统中断(CPU需要调度I/O线程),Processor会有什么样的行为?
Processor并不会就此等待中断处理完成,而是为了保证并发,将自己和另一个内核线程绑定,继续执行调度队列中的等待被执行的协程。当中断的协程被唤醒,则会将自己加入到另一个Processor的等待队列或者全局等待队列中。
当一个协程被中断,它在CPU寄存器中的状态会被保存在自己的协程对象中,重新获得执行机会时这一些状态会被写入到新的寄存器中继续运行。
通过以上调度可以看到,Groutine能够在不同的场景下仍然希望保持较高的并发继续执行来保证自己的高并发性能。
3. Groutine 示例代码
启动一个Groutine非常简单
go func(){}()
的方式
测试代码如下, 注意使用方法一的值传递方式启动go routine 。
package groutine_testimport ("fmt""testing""time"
)func TestGroutine(t *testing.T) {for i := 0; i < 10; i ++ {// 方法一: 正确go func(i int) { // 启动 一个 go routinefmt.Println(i)}(i)// 方法二:错误// 如下代码是有问题的// i 地址是被所有协程共享的,这个时候打印的结果// 会受到其他协程的影响// 想要保证代码的正确性,即每一个go routine打印// 各自的i 值,需要利用如上启动go routine的代码,// 进行值传递,从而让每个goroutine 独享各自的i的地址。// go func() {// fmt.Println(i)// }()}time.Sleep(time.Millisecond*50)
}
相关文章:

Java项目:美食菜谱分享平台系统设计和实现(java+springboot+mysql+ssm)
源码获取:博客首页 "资源" 里下载! 主要技术实现:spring、 springmvc、 springboot、mybatis 、session、 jquery 、 md5 、bootstarp.js tomcat、拦截器等。 具体主要功能模块如下: 1.用户模块管理:用户…

【leetcode】Roman to Integer
题目描述: Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999. 解题思路: 首先我们要了解罗马数字怎么写的 个位数举例 I, 1 】II, 2】 III, 3】 IV, 4 】V, 5 】VI, 6】 VII, 7】 VIII,8 】…

Apache Traffic Server管理工具
Traffic Line是命令行程序,可以用来快速监视 Traffic Server 的性能和网络流量,也能配置 TS。Traffic Shell也是命令行工具,进入该 shell 后有自己一套语法,可代替 Traffic Line 完成监控、配置任务。通过 Traffic Line 和 Traffi…

npm使用记录
npm是一个 包管理工具。安装node之后就可以使用npm命令了,为了方便使用,通常我们还要装下 淘宝NPM镜像,之后就可以用cnpm命令了。 注意:以下提到的如-g --save等标签都可以放在 包名前面。 首先一个前端项目下载下来,需…

Go 分布式学习利器(18)-- Go并发编程之lock+WaitGroup实现线程安全
Go语言中通过Groutine 启动一个Go协程,不同协程之间是并发执行的,就像C/Java中线程之间线程安全是一个常见的问题。 如下Go 语言代码: func TestConcurrent(t *testing.T) {var counter int 0for i : 0;i < 5000; i {go func() { // 启动groutine 进…

Java项目:网上家具商城平台设计和实现(java+springboot+mysql+ssm)
源码获取:博客首页 "资源" 里下载! 主要技术:springmvc springboot mybatis mysql jquery layui 等技术 具体功能模块: (1) 用户注册和登录登录功能: ①用户的注册功能 : 访问网站的人根据网站的提示注册…

Linux socket TIME_WAIT 优化
如发现系统存在大量TIME_WAIT状态的连接,通过调整内核参数解决,vim /etc/sysctl.conf编辑文件,加入以下内容:net.ipv4.tcp_syncookies 1net.ipv4.tcp_tw_reuse 1net.ipv4.tcp_tw_recycle 1net.ipv4.tcp_fin_timeout 30然后执行…

Android Handler的使用!!!
大家好我们这一节讲的是Android Handler的使用,在讲Handler之前,我们先提个小问题,就是如何让程序5秒钟更新一下Title.首先我们看一下习惯了Java编程的人,在不知道Handler的用法之前是怎么样写的程序,代码如下所示:view plaincopy to clipboa…

git之reset图解
https://blog.csdn.net/longintchar/article/details/81843048 1、三棵树。 此时如果我们运行 git status,会发现没有任何改动,因为现在三棵树完全相同。 修改文件 现在我们想要对文件进行修改然后提交它。我们将会经历同样的过程;首先在工作…

Go 分布式学习利器(19)-- Go并发编程 之 CSP(communicating sequential processes) 机制
文章目录前言CSP 特点CSP代码 演示1. 正常流程的代码2. CSP 未设置buffer 代码3. 设置指定大小的channel buffer总结前言 CSP 这个名词大家会比较陌生,但是说到future 熟悉C / JAVA 线程模型的伙伴可能就会很熟悉了, 通过future机制能够实现两个线程之间…

Java项目:学生学科竞赛管理管理系统设计和实现(java+springboot+ssm+maven)
源码获取:博客首页 "资源" 里下载! 主要技术、spring、 springmvc、 springboot、 mybatis 、 jquery 、 layUI、md5 、bootstarp.js tomcat、、拦截器等项目 主要功能:登录、用户、菜单管理、角色管理、权限管理、立项申请、报名、结、经费…

update 改写 merge into
update语句改写成merge into有时会提高运行速度 看两个案例 1.根据业务将两个嵌套子查询改写成max,速度有3min提升到3s UPDATE OPER_792.LL_SCB_YDKB_20120730 A SET A.DCP (SELECT B.PROD_OFFER_NAME FROM OPER_792.YD_TC B WHERE A.SERV_ID B.SERV_ID AND B.TC_…

CCControlSwitch 、CCControlSlider、CCControlButton
/**bool hasMoved(); 这里获取的不是开关是否正在被用户拨动,而是开关最终的状态是由用户手动拨动开关进行的,*还是用户点击开关进行的状态更改*/CCControlSwitch* pSwitch CCControlSwitch::create(CCSprite::create("switch-mask.png"),CCS…

bzoj2961 共点圆 (CDQ分治, 凸包)
/* 可以发现可行的圆心相对于我们要查询的点是在一个半平面上, 然后我们要做的就是动态维护凸壳然后用这个半平面去切它 看看是否是在合法的那一面然后cdq分治就可以了代码基本是抄的,*/#include<cstdio> #include<algorithm> #include<c…

Rocksdb Iterator实现:从DBIter 到 TwoLevelIter 的漫长链路
文章目录1. 迭代器简单介绍2. 迭代器用户态相关接口3. 迭代器内部架构4. 迭代器的入口实现4.1 DBIter4.2 MergingIterator4.3 Memtable系列Iterator4.4 LevelIterator 和 TwoLevelIteratorps:本文的基础迭代器设计 以及 相关代码 是基于rocksdb 6.4.6版本进行描述的…

Java项目:OA办公自动化系统设计和实现(java+springboot+freemarker+mysql+maven+mybatis+jpa)
源码获取:博客首页 "资源" 里下载! java springbootOA办公自动化系统: 主要功能模块:系统、用户、角色、考勤、流程、公告、邮件、任务、日程、计划、文件、笔记、通讯录、讨论区等多个模块管理 使用Maven进行项目管理…

UIScrollView上面放一个UIScrollView或者UITableView拖动时候 View出现一闪一闪解决办法...
在项目中发现一个问题: 创建一个UIScrollView 上面放一个scrollView或者TableView,拖动scrollview或TableView 画面出现一闪一闪的情况。 解决办法设置一下UIScrollView的contentSize 如果你是上下滑动scrollView.contentSize CGSizeMake(0, self.view.…

理解koa-router 路由一般使用
阅读目录 一:理解koa-router一般的路由二:理解koa-router命名路由三:理解koa-router多个中间件使用四:理解koa-router嵌套路由五:分割路由文件回到顶部一:理解koa-router一般的路由 koa-router是koa的路由库…

Go 分布式学习利器(20)-- Go并发编程之多路选择和超时控制,channel的关闭和广播
Select 多路选择 基本使用语法如下: select { case ret : <-retCh1: //阻塞事件,等待channel1的消息t.Logf("result %s \n",ret) case ret : <-retCh2:t.Logf("result %s \n", rest) default :t.Error("return empty&q…

Java项目:网盘系统设计和实现(java+ssm+jpa)
源码获取:博客首页 "资源" 里下载! 很多同学都有自己的网盘,方便存储一些java学习教程。该毕业设计实现了一个简易的网盘,包含文件上传和文件分享等功能。 后端技术采用了spring,spring mvc,JPA&…

快速学习的方法论
大多数人认为学习的快慢取决于学习者的天赋,实际上研究表明学习方法起着至关重要的作用。更深层次的知识加工,与时而反复的温故知新,在某些情况下会加倍你的学习效率。最近学习了如何快速学习的方法论,分享给大家。 是否能加速理解…

C#拉姆达(=)表达式
前言: 之前小猪曾经分享过自己对C#委托的一点理解 其实在使用委托的过程中我们会大量的使用拉姆达(>)表达式 介绍: "Lambda表达式"是一个匿名函数,是一种高效的类似于函数式编程的表达式,Lambda简化了开发中需要编写…
Python爬虫入门教程 57-100 python爬虫高级技术之验证码篇3-滑动验证码识别技术
滑动验证码介绍 本篇博客涉及到的验证码为滑动验证码,不同于极验证,本验证码难度略低,需要的将滑块拖动到矩形区域右侧即可完成。 这类验证码不常见了,官方介绍地址为:https://promotion.aliyun.com/ntms/act/captchaI…

FlameScope 更高级全面的火焰图
FlameScope 更高级全面的火焰图 文章目录FlameScope 更高级全面的火焰图安装步骤安装问题fix使用方式网飞(Netflix)开发的火焰图工具能够更好得呈现出一段时间内的服务器on/off cpu 的热力图。安装步骤 $ git clone https://github.com/Netflix/flamescope $ cd flamescope $ …

sql 基础--mysql 5 (6)
12.子查询 子查询进行过滤 mysql> select msg from pw_luck where name wang5-> ; ------ | msg | ------ | 1001 | | 1000 | | 1000 | | 100 | | 100 | ------ 5 rows in set (0.03 sec)mysql> select uid from pw_luck where msg in (select msg from pw_luck w…

Java项目:就业管理系统设计和实现(java+springboot+ssm)
源码获取:博客首页 "资源" 里下载! 就业管理系统: 该毕业设计采用了spring boot,spring,spring mvc,mybatis作为后端技术框架,这些组合稳定抗打,前端使用了layui,界面美观…

算法设计与分析之循环与递归
前言:循环与递归可以说是算法设计中最基本但却也是最重要的工具方法。循环和递归对于学习过高级程序设计语言的人来说都并不陌生,但还是有必要仔细的探究一下循环和递归之间的相似和区别。循环与递归最大的相似之处莫不是在于他们在算法设计中的工具作用…

面向对象与软件工程---团队作业1
1.队伍名称: 遥遥万里(还有很长路要走的意思) 2.队员信息: 陈雄(组长) 学号:1700509024 博客园链接:https://www.cnblogs.com/bearchan/ 廖鹏辉 学号:1700802007 博客园…

从paxos到raft zab,为何raft能够“独领风骚”
文章目录RAFT出现的缘由RAFT 的实现STATE MACHINELog Replicated State MachineLeader Election基本角色关键变量基本选举过程Log Replicated基本概念基本操作SafetyLog Replication: Consistency checkLeader Election: Leader Completeness总结RAFT 和 ZAB 的对比参考文献:阅…

Java项目:前台+后台精品水果商城系统设计和实现(java+Springboot+ssm+mysql+jsp+maven)
源码获取:博客首页 "资源" 里下载! 一、项目简述 本系统主要实现的功能有: 前台用户的登录注册,水果商品的展示,水果的购物车, 购物车新增结算等等,银行卡的支付绑定,收货…