写在文章开头
go语言
通过GMP模型
实现协程并发,为了避免单协程持续持有线程导致线程队列中的其他协程饥饿问题,设计者提出了一个抢占式调度机制,本文会基于一个简单的代码示例对抢占式调度过程进行深入讲解剖析。
Hi,我是 sharkChili ,是个不断在硬核技术上作死的 java coder ,是 CSDN的博客专家 ,也是开源项目 Java Guide 的维护者之一,熟悉 Java 也会一点 Go ,偶尔也会在 C源码 边缘徘徊。写过很多有意思的技术博客,也还在研究并输出技术的路上,希望我的文章对你有帮助,非常欢迎你关注我的公众号: 写代码的SharkChili 。
因为近期收到很多读者的私信,所以也专门创建了一个交流群,感兴趣的读者可以通过上方的公众号获取笔者的联系方式完成好友添加,点击备注 “加群” 即可和笔者和笔者的朋友们进行深入交流。
详解协程抢占式调度
函数调用间进行抢占式调度
假设我们现在有这样一个协程,它会进行函数嵌套调用,代码如下所示:
1 | scss复制代码func foo1() { |
我们给出运行结果:
1 | 复制代码foo1调用foo2 |
基于这段代码示例,我们通过这段指令获取plan9
汇编码:
1 | go复制代码go build -gcflags -S main.go |
可以看到在foo1
插入runtime.morestack_noctxt
方法,该方法是用于检查当前协程是否有足够的堆栈空间以保证函数的正常调用,基于这一点,go
就会在进行这部检查时顺带检查协程的执行时长,一旦超过10ms
该方法就会将协程设置为标记可被抢占:
1 | less复制代码 0x0061 00097 (F:\github\test\main.go:8) CALL runtime.morestack_noctxt(SB) |
如下图,我们的调用的函数都会被插入一个morestack
通过这个标记判断当前协程执行耗时,一旦发现超过10ms则会直接通过抢占式调度的方法g0
协程直接调用schedule
方法获取另外的协程进行调用:
这一点我们可以在asm_amd64.s
看到morestack
的newstack
的代码,而newstack就是实现抢占式调度的核心:
1 | scss复制代码TEXT runtime·morestack(SB),NOSPLIT,$0-0 |
上述的newstack
方法在stack.go
中,如果当前协程可被抢占则会调用gopreempt_m
回到g0
调用schedule
方法从协程队列中拿到新的协程执行任务:
1 | scss复制代码 |
基于系统调用发起信号的抢占式调度
假设我们的协程没有进行额外的函数调用,是否就意味着当前协程的线程不能被抢占呢?很明显不是这样:
- 网络传输过程中需要发送某些紧急消息希望通过已有连接迅速将消息通知给对端时,就会产生
SIGURG
信号,go
语言就会在收到此信号时触发抢占式调度。
- 进行
GC
工作时像目标线程发送信号由此实现抢占式调度。
对于第一点我们可以在signal_unix.go
的sighandler
方法得以印证,可以看到它会判断sig 是否为_SIGURG
若是则调用doSigPreempt
进行抢占式调度
1 | scss复制代码func sighandler(sig uint32, info *siginfo, ctxt unsafe.Pointer, gp *g) { |
doSigPreempt
会通过调用asyncPreempt
最终执行到preempt.go
的asyncPreempt2
调用到和上文函数调用抢占式调度方法gopreempt_m
回到schedule
方法从而完成抢占式调度:
1 | scss复制代码func doSigPreempt(gp *g, ctxt *sigctxt) { |
小结
以上便是笔者关于go语言中协程抢占式调度的所有内容,希望对你有帮助。
我是 sharkchili ,CSDN Java 领域博客专家,开源项目—JavaGuide contributor,我想写一些有意思的东西,希望对你有帮助,如果你想实时收到我写的硬核的文章也欢迎你关注我的公众号: 写代码的SharkChili 。 因为近期收到很多读者的私信,所以也专门创建了一个交流群,感兴趣的读者可以通过上方的公众号获取笔者的联系方式完成好友添加,点击备注 “加群” 即可和笔者和笔者的朋友们进行深入交流。
参考
TCP 带外数据(即紧急模式的发送和接受) :blog.csdn.net/liushengxi_…
Linux(程序设计):59—SIGHUP、SIGPIPE、SIGURG信号处理(附SIGURG信号处理普通数据与外带数据案例):blog.51cto.com/u_15346415/…
本文使用 markdown.com.cn 排版
本文转载自: 掘金