内核级线程和用户级线程的区别:
如果说用户级线程是使用了两个栈,那么内核级线程就是使用了两套栈(一套栈中包含用户栈和内核栈)。
用户级线程切换是先TCB切换,然后根据TCB切换用户栈;而核心级线程是先TCB切换,然后根据TCB来切换一套栈。
内核级线程中是由内核来管理TCB,由内核来负责切换线程;而在用户级线程中则由Yield函数来切换线程。
用户级线程中线程的切换是在用户态切换的,而内核级线程中线程的切换是在内核态切换的。
L11 内核级线程
内核级线程和用户级线程区别
内核级线程和用户级线程的区别:
如果说用户级线程是使用了两个栈,那么内核级线程就是使用了两套栈(一套栈中包含用户栈和内核栈)。
用户级线程切换是先TCB切换,然后根据TCB切换用户栈;而核心级线程是先TCB切换,然后根据TCB来切换一套栈。
内核级线程中是由内核来管理TCB,由内核来负责切换线程;而在用户级线程中则由Yield函数来切换线程。
用户级线程中线程的切换是在用户态切换的,而内核级线程中线程的切换是在内核态切换的。
用户栈和内核栈之间的关联
★当程序在用户态执行时,使用的是用户栈,但是当遇到中断指令INT后,操作系统就要进入内核态,通过计算机硬件找到该线程的内核栈,内核栈中存储了用户栈的SS和SP(SS:堆栈段寄存器,存放堆栈的段地址;SP:堆栈指针寄存器(stack pointer),存放堆栈的偏移地址。通过这个操作将用户栈和内核栈相关联起来),源程序的PC和CS(即源程序中断前的执行的函数的下一步的地址(CS,code segment代码段寄存器;IP,instruction pointer指令指针寄存器;PC,programme counter程序计数器。))。 当操作系统返回到用户态时,通过源SS和SP能找到该线程的用户栈,通过源PC和CS能找到用户栈中该线程的下一步函数执行地址,实现从内核态返回到用户态。
★注意:PC 是计算机科学中使用的一个术语。IP 是 x86 兼容 CPU 中的一个寄存器。简单来说,在 x86 兼容 CPU 上,CS 段寄存器和 IP 寄存器两个寄存器就是实现计算机科学中的 PC 这个概念的具体设施。(CS:IP是两个寄存器。通过两个寄存器的值的运算得到指令的地址,也就是PC的值。)
★★★用户栈和内核栈的切换以及线程切换
接下来以一个例子来讲述线程的用户栈和内核栈之间的切换以及线程和线程之间的切换:
首先是线程的用户栈和内核栈之间的切换:
如下图所示,一个线程包含用户程序和内核程序两部分,首先函数 A 调用函数 B ,并将 104 压入用户栈;然后函数 B 调用**库函数 read() **,并将 204 压入用户栈;read() 函数通过调用 int 0x80 中断进入内核态。
在内核态,首先通过计算机硬件找到该线程的内核栈,然后将用户栈的 SS 和 SP 压入内核栈,并将程序的 PC(这里是304)和 CS(这里是100)也压入内核栈,当返回到用户态时,就是通过SS:SP来找到用户栈,通过PC、CS来找到用户态中该线程的下一步函数执行地址。下图中又将1000压入内核栈,然后执行sys_read()。
然后是线程与线程之间的切换:
在内核态中,因为sys_read()函数启动读磁盘后由运行态变为阻塞态,所以要在内核态中进行线程的切换,由线程S切换到线程T,此时应该将线程S的 TCB.esp 置为当前esp的值,然后将esp置为线程T的 TCB.esp 的值,完成内核栈的切换(通过switch_to函数来完成),在完成内核栈的切换后,又通过SS:SP和PC、CS实现由线程(此时的线程是切换后的线程,即这里的线程T)的内核栈到线程的用户栈的切换。
注意:从用户态到内核态是通过中断指令 int 来实现的,而从内核态到用户态是通过 iret 指令来实现的,所以
????
处是一段包含 iret 指令的代码。★★★将上述过程总结一下,就是内核线程 switch_to 的五段论:
- 首先是线程S的用户栈切换到内核栈,通过 int 中断实现由用户态进入到内核态,并且在内核栈中存储用户栈的信息;
- 其次是线程S的内核栈可能由于读磁盘等因素发生中断,需要切换到下一个线程;
- 然后是要进行调度,得到要切换的下一个线程,这里是线程T;(schedule 是得到下一个要切换的线程)
- 接着是通过 switch_to 实现由线程S的内核栈切换到线程T的内核栈;(switch_to 是实现了切换)
- 最后是通过 iret 指令,由线程T的内核栈切换到线程T的用户栈,实现由内核态进入到用户态,完成线程的一套栈的切换。
Create函数
内核级线程的Create函数与用户级线程的Create函数类似,只不过还要多出一些东西。
内核级线程的Create函数需要创建:线程控制块TCB、内核栈、用户栈,并将TCB和内核栈相关联,将内核栈与用户栈相关联。