Go 进阶 · 分布式爬虫实战
郑建勋
Go 语言技术专家,《Go 语言底层原理剖析》作者
15839 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 58 讲
Go 进阶 · 分布式爬虫实战
15
15
1.0x
00:00/00:00
登录|注册

25 | 运筹帷幄: 协程的运行机制与调度器原理

你好,我是郑建勋。
Go 语言以容易编写高并发的程序而闻名。之前我们介绍 Go 语言的网络模型时,就提到了 Go 运行时借助对 I/O 多路复用的封装还有协程的灵巧调度,实现了高并发的网络处理。不过当时我们还没有深入地审视协程这一最重要的 Go 特性,所以在搭建高并发的爬虫模型之前,让我们先来深入看看协程的运行机制,以及调度器是如何实现灵巧调度的。

线程 VS 协程

协程一般被认为是轻量级的线程。线程是操作系统资源调度的基本单位,但操作系统却感知不到协程的存在,协程的管理依赖 Go 语言运行时自身提供的调度器。因此准确地说,Go 语言中的协程是从属于某一个线程的,只有协程和实际线程绑定,才有执行的机会。
为什么 Go 语言需要在线程的基础上抽象出协程的概念,而不是直接操作线程呢?要回答这个问题,就需要深入理解线程和协程的区别。下面我就简单从调度方式、上下文切换的速度、调度策略、栈的大小这四个方面分析一下线程和协程的不同之处。

调度方式

Go 语言中的协程是从属于某一个线程的,协程与线程的关系为多对多的对应关系。Go 语言调度器可以将多个协程调度到同一个线程中去执行,一个协程也可能切换到多个线程中去执行。

上下文切换的速度

协程上下文切换的速度要快于线程,因为切换协程不必同时切换用户态与操作系统内核态,而且在 Go 语言中切换协程只需要保留极少的状态和寄存器值(SP/BP/PC),而切换线程则会保留额外的寄存器值(例如浮点寄存器)。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Go语言协程的调度器原理是本文的重点内容。文章首先对比了线程和协程的区别,包括调度方式、上下文切换速度、调度策略和栈的大小。接着深入介绍了Go运行时是如何将协程与线程绑定在一起的,通过逻辑处理器P和特殊的调度协程g0的引入,优化了调度器的性能。调度器的核心策略位于schedule函数中,包括局部运行队列、全局运行队列以及调度算法。文章还介绍了调度时机分为主动调度、被动调度和抢占调度,并以通道的堵塞为例说明了被动调度的过程。此外,还详细解释了协程的上下文切换过程和协程的执行现场保存方式。Go运行时依靠着灵巧的调度实现了对于海量协程的管理,确保了CPU资源的高效利用。文章还介绍了抢占调度的机制,包括执行时间过长的抢占调度和陷入到系统调用中的抢占调度。总的来说,本文通过深入解析Go语言协程的运行机制和调度器原理,为读者提供了深入了解协程技术特点的内容。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Go 进阶 · 分布式爬虫实战》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(6)

  • 最新
  • 精选
  • Realm
    1. 谷歌开发者不建议大家获取协程ID,避免开发者滥用协程Id实现Goroutine Local Storage,滥用协程ID会导致GC不能及时回收内存. 2 协程池在大并发的场景中很有必要,虽然goroutine开销很小,无休止开辟Goroutine,会高频率的调度Groutine,在上下文切换上浪费很多资源. https://github.com/panjf2000/ants 这个是一个高性能协程池.
    2022-12-06归属地:浙江
    4
  • 一打七
    这节课太干了,全是干货,赞赞赞
    2022-12-07归属地:北京
    2
  • 牙小木
    没有goroutineId,Mutex就无法做到可重入。。
    2023-08-18归属地:北京
    1
  • 啦啦啦
    还有一类特殊的情况涉及到协程长时间堵塞在系统调用中的问题。这时,当前正在工作的线程会陷入等待状态,等待内核完成系统调用并返回 前面不是说Go用的非堵塞IO+Epoll,为什么M还会被堵住?
    2023-06-08归属地:新加坡
    1
  • 青鸟飞鱼
    协程因为在休眠、Channel 通道堵塞、网络 I/O 堵塞、执行垃圾回收而暂停时,被动让渡自己执行权利的过程。这个时候的G是放在局部运行队列吗?还是不是很合适,如果再次调度时,时机没到怎么办呢?
    2023-02-21归属地:四川
  • shuff1e
    谷歌开发者不建议大家获取协程ID,主要是为了GC更好的工作,滥用协程ID会导致GC不能及时回收内存。如果一个第三方库使用了协程ID,那么使用该库的人将会莫名中招。
    2022-12-06归属地:上海
收起评论
大纲
固定大纲
线程 VS 协程
调度方式
上下文切换的速度
显示
设置
留言
6
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部