Linux 按照特权等级,把进程的运行空间分为内核空间和用户空间,一次系统调用可以实现用户态和内核态的切换
线程是调度的基本单位,而进程则是资源拥有的基本单位
下面的x对y(x:y)即x个用户态线程对应y个内核调度实体(Kernel Scheduling Entity,这个是内核分配CPU的对象单位)
关键因子:用户态线程、用户态调度器、协程队列、上下文切换
其实就是用户态线程的一种调度方式,实现了用户态的上下文切换,配合一个用户态调度器与相应协程队列实现;
上下文切换方面,保存好当前的寄存器状态与栈就可以保存好当前的协程状态了(比如可以把寄存器值压到栈里然后栈和PC、SP存起来),恢复的时候就恢复寄存器值以及PC、SP,新建的时候就给个新的栈空间,运行完了就销毁对应的栈空间。不能用汇编的话就需要那个语言本身支持类似的上下文切换操作,比如python里的generator
有上下文切换的方法之后
在需要切换协程的地方保存当前上下文、恢复调度器协程的上下文
调度器协程选择下一个可以运行的协程——协程队列
调度器协程保存自己的上下文,恢复目标协程的上下文
串起来的话,程序运行入口注册好初始要运行的协程(加到可运行队列里),然后启动调度器协程,一个基本的协程框架就可以跑起来了
之后配合epoll之类的event loop,给协程不同的状态(运行中/可运行/阻塞,其实就很类似线程/进程的状态),调度器根据这些状态选择可运行的协程去运行,就是一个比较能用的协程框架了。
以上说的都是单内核线程下的情况,如果是多内核线程(比如Go的GPM模型),那还需要加一层各个协程到对应内核线程的映射,调度器实现会更复杂一点。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。