加入收藏 | 设为首页 | 会员中心 | 我要投稿 南京站长网 (https://www.025zz.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Unix > 正文

走近内核级线程——切换五段论

发布时间:2022-12-12 13:31:40 所属栏目:Unix 来源:互联网
导读: 前面我们提到用户级线程的切换,是通过切换线程栈来实现的,由TCB线程控制块来控制,用户自己就能实现,无需通过内核。这次我们来讲讲内核级线程以及它的切换。
内核级线程,顾名思义,就是

前面我们提到用户级线程的切换,是通过切换线程栈来实现的,由TCB线程控制块来控制,用户自己就能实现,无需通过内核。这次我们来讲讲内核级线程以及它的切换。

内核级线程,顾名思义,就是处于内核态的线程,对于内核级线程,可以很好配合多核CPU,多核指的是MMU(映射)一样,但是有多个核可以并行的处理事件。

unix线程切换_线程切换 进程切换_unix环境高级编程和unix网络编程哪本好

这就是操作系统的进程线程示意图,可以看到只有核心级线程可以很好的利用邮件条件,多核CPU等

回顾上次所说的用户级线程的切换,是两个栈之间的切换,那核心级线程的切换是什么呢?不是两个栈,而是两套栈。因为核心级线程必须到内核态,在用户态使用用户栈,在内核态不也得调用函数unix线程切换,也得使用一个栈,既要在用户态又得在内核态跑,一个核心级线程要两个栈组成的一套栈。

对比用户级线程的切换使用TCB进行切换,核心级线程也用TCB切换,不过这个TCB在内核中,而且根据TCB的切换来切换一套栈,内核栈和用户栈都得切换。

那么具体的如何从一个核心级线程切到另一个核心级线程呢?这就是大名鼎鼎的五段论了。首先我们得从当前的用户栈切到内核栈,只有通过系统中断才可以进入内核,INT就是系统中断,通过在内核栈里面存储SS,SP来记录切换回来的指针,我们就可以切入内核栈了,如果想返回,可以调用IRET的系统调用返回,这就是一套栈了。

      100A(){
          B();
          104;
      }
      200B(){
        read();
        204;
      }
用户程序300:read(){
|        int 0x80;
|        304; 
|      }
|      system_call;
内核程序call sys_call
     1000; 
     2000:sys_read(){     } 

如上图,我们调用read()调用系统中断进入内核态,现在的栈的情况是

用户栈:104
        204
内核栈:SS SP(记录返回指针)
        EFLAGS
        304
        CS
        1000

可以看到这两个栈配合的非常好,这就是一套栈的精髓所在,也完成了切换的第一段。

由于read需要读磁盘,这会使线程进入堵塞阶段,引发CPU调度,switch_to通过TCB的切换(第二段)找到另一个线程B的内核栈的指针,然后切到另一套栈(第三段),也就是线程的切换,这是切换的第二、三段。

但是我们执行的是用户的函数,所以我们还得切到线程B的用户栈(第四段),这里我们执行完内核栈的函数,通过弹栈中断返回到SS SP弹回线程B的用户栈,这就是切换的第五段。

如果是进程的切换的话,我们另外切换地址映射表就可以了。

以上就是内核级线程切换的switch_to五段论。下次我们再讲讲内核级线程是如何是实现的,它的源码是什么样的呢?以及后面综合的内核级线程和用户级线程的比较对照。

(编辑:南京站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章