解决Golang中goroutine执行速度的问题
来源:脚本之家
2022-12-23 11:40:42
0浏览
收藏
本篇文章向大家介绍《解决Golang中goroutine执行速度的问题》,主要包括goroutine,具有一定的参考价值,需要的朋友可以参考一下。
突然想到了之前一直没留意的for循环中开goroutine的执行顺序问题,就找了段代码试了试,试了几次后发现几个有意思的地方,我暂时没有精力往更深处挖掘,希望有golang大神能简单说一说这几个地方是怎么回事。
代码:
package main import "fmt" func Count(ch chan int) { fmt.Println("Count doing") ch <p>试了几次之后,反复的想goroutine执行的问题。</p> <h2>根据下面的输出,我能看到的是:</h2> <p>1. for循环的速度 比 for中开出goroutine并执行的速度 执行的快</p> <p>2. 但是 开goroutine和执行第一个fmt的速度可能赶上 for循环的速度 比如前12个count和count doing</p> <p>3. 关键问题,第二个for循环执行的fmt竟然要比goroutine中的第二个fmt快??(放入channel很耗时?)</p> <p>4. main结束时,也就是第二个for循环结束时, 还有goroutine中的第二个fmt没执行</p> <h2>输出:</h2> <pre class="brush:plain;"> Count 0 Count 1 Count 2 Count 3 Count 4 Count 5 Count 6 Count 7 Count 8 Count 9 Count 10 Count 11 Count doing Count doing Count doing Count doing Count doing Count 12 Count doing Count doing Count doing Count doing Count doing Count doing Count doing Count 13 Count 14 Count 15 Count 16 Count 17 Count 18 Count 19 Count 20 Count 21 Count doing Count doing Count doing Count 22 Count doing Count doing Count doing Count 23 Count 24 Count 25 Count 26 Count 27 Count 28 Count 29 Count 30 Count doing Count 31 Count doing Count doing Count 32 Count 33 Count 34 Count 35 Count doing Count 36 Count doing Count doing Count 37 Count 38 Count doing Count doing Count doing Count doing Count 39 Count 40 Count 41 Count 42 Count 43 Count doing Count doing Count 44 Count 45 Count 46 Count 47 Count doing Count 48 Count 49 Count doing Count doing Count 50 Count 51 Count doing Count doing Count doing Count doing Count doing Count 52 Count 53 Count doing Count doing Count doing Count doing Count 54 Count doing Count 55 Count 56 Count 57 Count 58 Count 59 Count 60 Count 61 Count 62 Count 63 Count 64 Count 65 Count doing Count doing Count doing Count 66 Count 67 Count 68 Count 69 Count doing Count 70 Count doing Count 71 Count 72 Count doing Count 73 Count doing Count doing Count 74 Count doing Count 75 Count 76 Count 77 Count doing Count doing Count doing Count doing Count 78 Count 79 Count 80 Count 81 Count 82 Count 83 Count 84 Count 85 Count 86 Count 87 Count 88 Count 89 Count 90 Count 91 Count 92 Count 93 Count 94 Count doing Count doing Count doing Count doing Count doing Count doing Count doing Count doing Count 95 Count doing Count 96 Count doing Count 97 Count 98 Count doing Count 99 Count doing Count doing Counting 0 Counting 1 Counting 2 Counting 3 Counting 4 Counting 5 Counting 6 Count doing Count doing Counting 7 Counting 8 Count doing Counting Count doing Counting 9 Counting Count doing Count doing Count doing Count doing Count doing Counting Count doing Count doing Count doing Counting Count doing Counting Count doing Counting 10 Counting 11 Counting Count doing Count doing Count doing Count doing Count doing Count doing Counting Count doing Count doing Counting Counting Count doing Count doing Count doing Count doing Counting Count doing Counting Count doing Count doing Counting 12 Counting 13 Counting 14 Counting 15 Counting 16 Counting 17 Counting 18 Counting 19 Counting 20 Counting 21 Counting 22 Counting 23 Counting 24 Counting 25 Counting 26 Counting 27 Counting 28 Counting 29 Counting 30 Counting 31 Counting 32 Counting 33 Counting 34 Counting 35 Counting 36 Counting 37 Counting 38 Counting 39 Counting 40 Counting 41 Counting 42 Counting 43 Counting 44 Counting 45 Counting 46 Counting 47 Counting 48 Counting 49 Counting 50 Counting 51 Counting 52 Counting 53 Counting 54 Counting 55 Counting 56 Counting Counting Counting Counting Counting Counting Count doing Counting Count doing Counting Counting Counting 57 Counting 58 Counting 59 Counting 60 Counting 61 Counting 62 Counting 63 Counting 64 Counting 65 Counting 66 Counting 67 Counting 68 Counting 69 Counting 70 Counting 71 Counting 72 Counting 73 Counting 74 Counting 75 Counting 76 Counting Counting Counting Counting Counting Counting Counting Counting Counting Counting Counting Counting Counting Counting Counting Counting Counting Counting Counting Counting 77 Counting 78 Counting 79 Counting 80 Counting 81 Counting 82 Counting 83 Counting 84 Counting 85 Counting 86 Counting 87 Counting 88 Counting 89 Counting 90 Counting 91 Counting 92 Counting 93 Counting 94 Counting 95 Counting 96 Counting 97 Counting 98 Counting 99
补充:【golang】goroutine调度的坑
今天说说我遇到的一个小坑, 关于goroutine 调度的问题。
关于goroutine的调度,网上资料已经一大堆了,这里就不再赘述了。
还是简单的说一下我理解的goroutine的调度。goroutine是语言层面的,它和内核线程是M:N的关系,并且用了分段栈,是相当轻量了。
如果设置runtime.GOMAXPROCS为1,那么会有一个上下文G,在G上会有一个对应的内核线程M,内核线程M上可以对应很多个goroutine记作G,每个上下文都会有一个队列称作runqueue,在用go关键字开启一个goroutine的时候,该goroutine就会被装入runqueue中,然后被M用来执行,如果刚好有两个goroutine在队列里,先执行的goroutine因为执行一些耗时操作(系统调用,读写 channel,gosched 主动放弃,网络IO)会被挂起(扔到全局runqueue),然后调度后面的goroutine。
好,重点在这里,看一下下面的一段代码
func main(){ runtime.GOMAXPROCS(1) waitGroup.Add(1) go func(){ defer waitGroup.Done() for i := 0;i <p>这段代码你运行,你会发现,永远都会被阻塞住,hello永远都打印不出来</p> <h2>好,这里出现了两个问题</h2> <p>1.为什么死循环的goroutine总是先运行?按理说不应该是随机的吗?</p> <p>2.为什么死循环的goroutine会阻塞而没有被挂起?</p> <p>先看第二个问题。这里的话,我当时也很苦恼,于是在网上发了问题,得到的回复是,死循环不属于上述任何一种需要被挂起的状态,于是死循环的goroutine会一直运行,想象一个高并发的场景,如果其中一个goroutine因为某种原因陷入死循环了,当前执行这个goroutine的OS thread基本就会被一直执行这个goroutine,直到程序结束,这简直是一场灾难。但是,1.12 会修正这个小问题。我们还是默默的等待新版本发布吧。</p> <p>再看第一个问题。为什么死循环的goroutine总是先运行?按理说不应该是随机的吗?测试过很多次,都是第二个goroutine先运行。嗯,其实就算是第二个goroutine先运行也是具有随机性的,这关于golang的编译器如何去实现随机。看一下大佬的回答 :</p> <p> </p><p>所以你要把它看作是随机的,不能依赖这种未确定的行为,不然很可能新版的编译器就会破坏你依赖的事实。有些项目不敢升级编译器版本,就是因为依赖了特定版本的编译器的行为,一升级就坏了。</p> <p>不是你自己测试很多遍你就能依赖它,编译器、操作系统、硬件等等不同,都有可能出现不同的结果。可以依赖的只有语言规范( https://golang.org/ref/spec ),编译器实现者是一定会遵守的。</p> <p>到这里也算是解决了上述的两个问题了。</p> <h2>来看一下另外一个版本</h2> <pre class="brush:plain;"> func main(){ runtime.GOMAXPROCS(1) waitGroup.Add(1) go func(){ defer waitGroup.Done() for { } }() waitGroup.Add(1) go func(){ defer waitGroup.Done() for i := 0;i <p>执行结果是,会先打印一个hello,然后陷入死循环,这也是说明了goroutine在遇到耗时操作或者系统调用的时候,后面的代码都不会执行了(request successful 没有被打印),会被抛到全局runqueue里去,然后执行runqueue中等待的goroutine</p> <p>希望能够帮助和我一样正在学习golang的友军们更好的理解goroutine的调度问题</p> <p>以上为个人经验,希望能给大家一个参考,也希望大家多多支持golang学习网。如有错误或未考虑完全的地方,望不吝赐教。</p><p>今天带大家了解了goroutine的相关知识,希望对你有所帮助;关于Golang的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~</p>
版本声明
本文转载于:脚本之家 如有侵犯,请联系study_golang@163.com删除

- 上一篇
- golang 比较浮点数的大小方式

- 下一篇
- 解决golang结构体tag编译错误的问题
评论列表
-
- 怕黑的耳机
- 这篇文章真及时,细节满满,很有用,码住,关注作者大大了!希望作者大大能多写Golang相关的文章。
- 2023-04-13 00:54:25
-
- 端庄的大树
- 感谢大佬分享,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,帮助很大,总算是懂了,感谢作者大大分享技术贴!
- 2023-01-06 04:59:06
-
- 活力的小懒猪
- 这篇文章内容出现的刚刚好,太细致了,受益颇多,已加入收藏夹了,关注up主了!希望up主能多写Golang相关的文章。
- 2023-01-03 20:08:49
查看更多
最新文章
-
- Golang · Go教程 | 10小时前 |
- TigervncDebian多用户共享桌面超简单教程
- 482浏览 收藏
-
- Golang · Go教程 | 1天前 |
- Go语言新手必看!切片vs数组,一次搞定这两个核心知识点
- 472浏览 收藏
-
- Golang · Go教程 | 1天前 |
- Docker在Debian上运行超简单教程(保姆级教学)
- 210浏览 收藏
-
- Golang · Go教程 | 1天前 |
- Debian设置hostname踩坑记录:权限问题大揭秘
- 334浏览 收藏
-
- Golang · Go教程 | 1天前 |
- Debian装SQLServer?这些问题你一定要注意!
- 284浏览 收藏
-
- Golang · Go教程 | 1天前 |
- Debian系统下Jenkins自动化部署脚本教学
- 367浏览 收藏
-
- Golang · Go教程 | 2天前 |
- DebianSwap服务器应用实测,这些场景真的用得上!
- 319浏览 收藏
-
- Golang · Go教程 | 2天前 |
- Debian跑TigerVNC实测!真香警告,快来看看性能咋样~
- 171浏览 收藏
-
- Golang · Go教程 | 2天前 |
- 在Debian上玩转SQLServer备份还原,手把手教你一步步操作
- 498浏览 收藏
-
- Golang · Go教程 | 2天前 |
- DebianOverlay不会玩?手把手教你轻松定制化安装
- 258浏览 收藏
-
- Golang · Go教程 | 2天前 |
- Go语言实战:time.Ticker&time.After用法区别及避坑技巧
- 240浏览 收藏
-
- Golang · Go教程 | 2天前 |
- Debian系统如何快速定位&干掉那些讨厌的僵尸进程
- 317浏览 收藏
查看更多
课程推荐
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
查看更多
AI推荐
-
- 茅茅虫AIGC检测
- 茅茅虫AIGC检测,湖南茅茅虫科技有限公司倾力打造,运用NLP技术精准识别AI生成文本,提供论文、专著等学术文本的AIGC检测服务。支持多种格式,生成可视化报告,保障您的学术诚信和内容质量。
- 14次使用
-
- 赛林匹克平台(Challympics)
- 探索赛林匹克平台Challympics,一个聚焦人工智能、算力算法、量子计算等前沿技术的赛事聚合平台。连接产学研用,助力科技创新与产业升级。
- 48次使用
-
- 笔格AIPPT
- SEO 笔格AIPPT是135编辑器推出的AI智能PPT制作平台,依托DeepSeek大模型,实现智能大纲生成、一键PPT生成、AI文字优化、图像生成等功能。免费试用,提升PPT制作效率,适用于商务演示、教育培训等多种场景。
- 56次使用
-
- 稿定PPT
- 告别PPT制作难题!稿定PPT提供海量模板、AI智能生成、在线协作,助您轻松制作专业演示文稿。职场办公、教育学习、企业服务全覆盖,降本增效,释放创意!
- 51次使用
-
- Suno苏诺中文版
- 探索Suno苏诺中文版,一款颠覆传统音乐创作的AI平台。无需专业技能,轻松创作个性化音乐。智能词曲生成、风格迁移、海量音效,释放您的音乐灵感!
- 56次使用
查看更多
相关文章
-
- Go语言使用goroutine及通道实现并发详解
- 2023-01-02 221浏览
-
- 如果用go写一个高性能点的聊天服务器应该怎么写?
- 2023-02-16 433浏览
-
- GoLang使goroutine停止的五种方法实例
- 2022-12-30 106浏览
-
- Go语言CSP并发模型goroutine及channel底层实现原理
- 2022-12-31 451浏览
-
- Go并发的方法之goroutine模型与调度策略
- 2023-01-01 331浏览