【协作式原创】查漏补缺之Goroutine的调度(预备知识)
几个概念
Linux进程和线程
用户态和内核态
-
系统调用将Linux整个体系分为用户态和内核态(或者说内核空间和用户空间)// 参考附录4
-
内核虚拟内存的构造 // 参考附录1
-
以32位为例,有4G虚拟地址空间。
用户代码可以访问3G的内存空间,内核代码可以访问1G的内存空间,分别就对应程序用户态和内核态。
用户代码通过系统调用,可以间接访问内核的1G的内存空间。
内核线程和用户线程
内核线程: 就是上面说的LWP(tgid=pid主线程,tgid!=pid子线程),受OS感知和调度的。检查 /proc/[pid]/task,这里有的就是内核级线程。
用户线程: 属于应用程序自己创建的。用户态线程需要绑定内核态线程去运行。
用户线程,用户态线程,协程,User-level threads, Application-level threads, Green threads // 参考附录2
User-level threads, Application-level threads, Green threads都指一样的东西,就是不受OS感知的线程,如果你Google coroutine相关的资料,会看到它指的就是用户态线程,在Green threads的维基百科里,看Green threads的实现列表,你会看到好很多coroutine实现,比如Java、Lua、Go、Erlang、Common Lisp、Haskell、Rust、PHP、Stackless Python,所以,我认为用户态线程就是协程。
其他可能有用的东西
系统调用的过程 // 参考-极客时间-趣谈linux系统
![](https://img2018.cnblogs.com/blog/900073/202002/900073-20200229134100666-1280948553.png)
Q: 为什么要设计出用户态和内核态?
A: 操作系统的核心是内核kernel,是独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。
为了保证用户进程不能直接操作内核,保证内核安全,操作系统将虚拟空间划分为两个部分:内核空间、用户空间。// 参考附录1
如何探索 Go 调度器的源码,验证想法
Linux Processes Series: part 1, part 2, part 3, part 4
fork(),exec(),wait()的综合用法C代码 && 创建进程的2种方式(fork,exec)
UNIX / Linux Processes: C fork() Function功能和用法