L6 内核级线程

由于Linux0.11中并未实现线程,因此本文主要以理论分析为主来介绍内核级线程。内核级线程与进程的主要区别在于是否需要进行资源的切换,本文中的内核级线程也是模仿进程来设计的,若想通过一个实际案例来分析线程可以参考实验4:基于内核栈切换的进程切换,实验4中对进程切换时的栈结构变化进行详细介绍。

相较与用户级线程来说,内核级线程能够被操作系统内核“感知”到,在分配CPU资源时,内核级线程会更加有优势。

用户级线程与内核级线程

图1 用户级线程与内核级线程

1 内核级线程的栈结构

1.1 从一个栈到一套栈

用户级线程中每一个线程都有一个用户栈,以确保在切换过程中不发生混乱。内核级线程需要进入操作系统内核,为了在切换的时候不发生混乱,一个内核级线程需要对应一套栈:用户栈+内核栈,当线程在用户态执行时就使用用户栈,当线程进入内核运行时就使用内核栈。下图为“一套栈”的结构示意图:

图1.1 “一套栈”的结构示意图

图中的线程内核栈和之前分析过的进程内核栈很相似,其实它们的创建方式是一样的。

1.2 用户栈与内核栈的关联

如何将用户栈与内核栈关联起来呢?即用户栈与内核栈之间如何切换。用户程序可以通过中断(如"int 0x80")进入内核,并切换到内核栈。当特权级发生改变时,执行中断会将SS:SP、EFLAGS、CS:IP这些寄存器压入内核栈中。当中断返回时,"iret"指令将SS:SP、EFLAGS、CS:IP出栈,从而切换回用户栈。下图很好的描述了这一过程。

用户栈与内核栈的关联

图1.2 用户栈与内核栈的关联

2 内核级线程的切换过程

与用户级线程不同,内核级线程的切换是在内核中进行的。内核级线程的切换大致经过如下过程(内核线程切换的五段论):

  1. 中断入口。这个中断可以是系统时钟中断,也可以是系统调用,该过程主要是将SS:SP、EFLAGS、CS:IP 压入到该线程的内核栈中。由于刚刚进入内核,因此这些寄存器记录的还是用户态的信息。
  2. 找到下一个线程的TCB,切换TCB。这个过程和进程切换PCB是类似的,也可以通过队列找到下一个需要执行的线程,然后切换TCB(TCB中有内核栈指针)。
  3. 切换内核栈。在用户级线程中切换栈的工作是由Yield()完成的,在内核级线程中切换内核栈的工作由switch_to函数完成,但其实Yield()和switch_to没有什么本质区别,只是名字不一样而已。切换内核栈的过程和切换用户栈类似,利用switch_to中的"ret"指令切换到下一个线程的内核栈。
  4. 中断出口,从内核栈切换回用户栈。通过中断返回指令"iert"将内核栈中SS:SP、EFLAGS、CS:IP(进入中断时压入的寄存器信息)弹出,从而切换到用户栈。

这里有个问题:进入中断后,系统是如何找到该线程的内核栈的?课程中老师只是简单的说通过硬件寄存器,系统会自动找到该线程的内核栈。个人认为这个硬件寄存器应该是 TR 寄存器,这个过程应该和进程进入内核后自动找到该进程的内核栈是类似的。

3 创建内核级线程

内核级线程和进程相似的,创建内核级线程可以参考fork()创建子进程。内核级线程的创建工作是由 ThreadCreate() 完成的,ThreadCreate() 需要在内核中执行,其基本流程如下:

void ThreadCreate(*func){
    TCB tcb=get_free_page();      //1、获取一页内存,TCB在这页内存的地址最小处
    *krlstack=PAGE_SIZE+(long)tcb;//2、设置内核栈在这页内存的地址最大处
    *userstack = ...;             //3、创建用户栈空间
    ...;                          //4、填充用户栈和内核栈。其中用户栈需要压入
                                  //CS:IP地址,而内核栈需要压入SS:SP、EFLAGS、CS:IP
    tcb.esp=krlstack;             //5、在tcb中保存内核栈指针
    tcb.状态=就绪;                 //6、将线程设置为就绪态
    tcb入队;                       //7、将tcb添加到总调度队列中
}

在线程创建完成后,线程就可以执行自己的程序了(func())。

参考

图1和图1.2 截取自哈工大操作系统课程的课件。

[1] 操作系统-哈尔滨工业大学-中国大学MOOC
[2] 哈工大操作系统实验手册
[3] Linux内核完全剖析——基于0.12内核

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值