什么是内核级的进程/线程
我自己的理解:
上一篇L10中所说的是用户级的线程,而进程没有用户级的,正在运行的程序就是进程,而进程可以说是操作系统直接管理的!
所以所谓的内核级进程是不成立的,只有内核级线程!这种说法也几乎等价于进程(当然细节上有很多不同)
内核级线程不同于用户级!它是直接被操作系统调度控制和管理的!而且有两套栈
内核级线程的两个栈
内核级线程/进程不单单在用户空间拥有自己的栈,同时在内核中拥有另一个栈
如图:
在内核栈中存储了:
线程用户态的ss和sp(栈底和栈顶)(这相当于将内核栈和用户栈连接了起来;)
应用程序的pc 和 cs(这俩用来指向当前执行到的程序位置)
所以说,当用户态通过中断进入内核态时,内核通过传入的参数查找TCB,将它们完全连接在一起
而当中断操作结束时,IRET返回弹栈,又能够回到当初中断结束的位置继续执行;
用户态线程切换的具体流程
从们从下面两个图中的具体例子,走一遍,然后总结过程
切换流程:
- 用户态:
①A()函数调用B()函数,104入用户栈
②函数B()调用read()系统调用,204入用户栈
③read()系统调用函数,产生中断int 0x80,当前pc指针指向 304(注意PC不入用户栈,由中断传入内核) - 内核态:
④:中断处理:生成内核栈:保存源SS:SP(形成连接)保存用户态pc(304)保存用户态cs(代码段基址);call sys_read:先将1000入栈,然后调用sys_read中断处理函数
⑤:read函数使用磁盘,因此当前线程阻塞,调用schedule()调度后,通过switch_to切换到next线程
⑥:switch_to中通过next的TCB,将cpu的esp指针指向next.TCB.esp,完成从内核栈到内核栈的切换
⑦:最后调用iret(中断返回),将线程T的TCB内容完成从内核态回到用户态 - 用户态:
⑧:线程T(新切换到的线程)开始继续执行
switch_to 细节五段论:
总结:
①中断陷入内核
②中断处理保存用户栈信息与内核栈相连,调用中断处理函数
③如果阻塞:调用schedule调度,和switch_to完成内核栈切换
④使用新的内核栈返回用户态继续运行用户态进程/线程;