We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在之前的channel分析中,遇到gopark和goready的调用。专门开设一篇笔记分析goroutine调度中用到的这两个函数。
The text was updated successfully, but these errors were encountered:
当我们使用Go编程时,程序并发运行时,对于操作系统仍是线程在运行程序指令,但是对于Go层面,加入了协程(goroutine)的机制。
协程(goroutine)
所以线程运行指令就变成了协程运行,从而有了协程运行的基本流程是(main函数也对应着协程):
由于程序中,不止有少数的几个协程在运行,所以就会出现协程调度,其主要作用是:
有上面的点,引出了:
在分析channel的底层实现时,可以看到当协程阻塞时会调用gopark。
gopark
2.1、看源码前的思考
先记录一些自己的猜测和想法。
在把正在运行的goroutine切换下来时,我们需要做下列一些工作:
Sorry, something went wrong.
schedule
答: 理论上来说,对于程序运行时来说,进程/线程/协程都是一段指令代码,程序运行的过程就是CPU顺序执行指令的过程。
CPU具体执行那一条指令,取决于PC寄存器,所以想要运行另一个Goroutine的话,只需要把PC寄存器设置为新的Goroutine的指令地址后即可。
PC寄存器
那么,实际上Go是如何实现的呢?在execute()函数中,运行新的Goroutine时,会调用gogo(&gp.sched)函数做切换。
对于gogo函数是汇编实现。
TEXT runtime·gogo(SB), NOSPLIT, $0-8 // 省略其他代码 MOVQ gobuf_pc(BX), BX // 将上次保存的PC地址读取出来 JMP BX // 跳转到上次保留的PC地址
通过更新PC寄存器,然后跳转到对应的地址,即可实现Goroutine的切换。
No branches or pull requests
在之前的channel分析中,遇到gopark和goready的调用。专门开设一篇笔记分析goroutine调度中用到的这两个函数。
The text was updated successfully, but these errors were encountered: