go协程学习笔记

协程本质:

go协程本质上还是用线程来运行代码,只是在多线程上增加了调度器,通过调度器让每一个线程可以执行多个协程。

实现原理:

go协程使用GPM调度模型实现,具体内容如下:

G goroutine协程

P process 调度器,为每一个m分配g,

M machine 对应操作系统的线程,g的真正执行者。

P的数量默认是CPU核数,也可以通过GOMAXPROCS来指定数量,每个P都会维护一个runq队列,用于保存G,P会从队列头获取G交给M执行,执行完后放入到队列尾(如果需要继续执行),通过GPM模型实现了多个协程并行(不是并发)执行,可以最大限度地利用到CPU。

协程优点:

协程相对于多线程有哪些优点呢?

1.上下文切换更轻量

触发go上下文切换有两种场景,1是协作式抢占引起的协程切换,2是锁阻塞\IO阻塞\channel阻塞,两种场景保存的上下文数据结构都是g.sched,它的数据结构如下:

与栈相关的SP和BP寄存器

PC

用于保存函数闭包的上下文,也就是DX寄存器

相比多线程协程切换只需要修改少数寄存器内容,所以更轻量,但一个线程使用到的寄存器总大小非常有限,就算全部内容更新也不会消耗多少资源, 但为什么大部分人都会说协程减少了上下文切换带来的开销? 这里就要看上下文的定义了,如果不仅包括协程执行时所需要的数据,还包括内核态与用户态的切换则这句是对的。

2.节省了内核态与用户态的切换

用户态切换与内核态之间切换一次可能花费1000cycles,线程切换由操作系统内核完成,所以需要从用户态切换到内核态然后再切回用户态,而协程则不需要进行状态的切换。

下面这段话测试结果描述了上下文切换带来的损耗:

Since all the context switching is happening at the application level, we don’t lose the same ~12k instructions (on average) per context switch that we were losing when using Threads. In Go, those same context switches are costing you ~200 nanoseconds or ~2.4k instructions.

摘自:https://www.ardanlabs.com/blog/2018/08/scheduling-in-go-part2.html

3.提高了IO类任务的效率?

CPU执行线程是抢占式的,GO协程也是协作抢占式,工作原理都一样,都是为每次执行分配固定的时间片,如果只从这一点看,它们执行io类任务效率不会有多大差别,但实际上产生效果还是有区别的,这个后面会提到。

协程引发的思考

1.操作系统需要支持协程吗?

协程能减少线程切换带来的开销,那操作系统有必要开发一种支持协程的线程吗,或者用其它方式支持协程的API?  如果这样做确实可以降低用户或各语言的开发难度,那这种方案可行吗?或者有必要吗?

个人觉得虽然可行但没必要,这样会提高系统的复杂性,尤其是协程队列的维护,这样的功能更贴近业务应该让各开发语言来实现,而不是底层的操作来实现,那这里又引发了另外一个思考:java需要支持协程吗?

2. java需要支持协程吗?

暂时不会支持,以后可能会有,理由是JAVA的线程池同样也有协程带来的开销减少好处,虽然写协程代码更简洁方便,但JDK1.8开始函数式编程的完善让我们创建线程更快捷了。不过如果JAVA支持协程确实会带来一些执行效果上的改变,例如前面提到的IO类任务,在线程池方案中,只有当前活跃的线程会拿到CPU时间片,如果这些线程是IO类会导致正在排队的其它任务长时间不能执行,这样大大降低了CPU利用率,虽然提高线程池活跃数能解决一部分问题,但还是做不到像协程那样每个任务都能公平分配到时间片,所以JAVA实现协程还是有一点点价值的,同样运行在java虚拟机上的Kotlin就支持协程。

求助:

因本人的知识储备与时间有限,有些问题还需要求助网友:

进程内线程切换会触发内核态与用户态的切换吗?

在网上查资料用户态切到内核态有以下三种情况:

1.当程序使用到系统内核的数据或者程序时就需要进入内核态

2.硬件出现异常,会优先执行系统程序

3.程序出现系统级错误

进程内线程切换一般是时间片用完,这种情况并不属于以上三种,那它会触发内核态与用户态的切换吗

问题知乎地址:https://www.zhihu.com/question/451104554

大家帮忙在知乎上回答这个问题,也可以钉钉我一起讨论:jeff07,当然上面笔记有描述错误也欢迎指正。

名词解释:

协作式抢占:sysmon 协程标记某个协程运行过久, 需要切换出去, 该协程在运行函数时会检查栈标记, 然后主动调用GoSched()让出CPU。

SP:stack pointer register 栈指针寄存器(指向栈顶)

BP: base pointer register  基指针寄存器

DX: 通用寄存器中的数据寄存器

参考:

https://mcll.top/2020/04/14/go%E7%9A%84%E5%8D%8F%E7%A8%8B%E4%B8%8A%E4%B8%8B%E6%96%87%E5%88%87%E6%8D%A2/

https://www.zhihu.com/question/20862617

参考重要摘要:


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容