进程管理、内核级线程、用户级线程

一:进程管理

1.进程本身的组织

每个进程都被封装在PCB里面(是一个数据结构),里面装有进程的信息。(比如数据段代码段的位置)

2.进程管理:PCB+进程状态+对应进程状态的队列。
3.多个进程之间如何进行切换?

当前进程启动磁盘读写,不适用CPU了,就把他放到等待队列里面,然后schedule(),schedule()函数先从等待队列里面取出一个进程的PCB。然后把原来进程的PCB转换成现在取出进程的PCB。


具体怎样转换呢?当前线程执行到一半结束了,肯定要保存当前线程使用的寄存器情况把?还要修改寄存器的状态吧?当然还需要记录代码执行到哪里了吧?答案是肯定的
//另外切换的时候不光要切换进程还要切换映射表(每个进程都有一个映射表,规划了这个进程在内存之中的分布,进程可以通过映射表访问到物理地址)
切换进程=切换指令流(线程切换)+切换资源(内存相关)

4.多个进程在内存中分离

通过映射表实现。

5.没有用户级进程

只有核心级进程,因为进程需要访问底层资源。

二: 用户级线程(yield线程)

1.线程切换
  • 一个进程内部的线程切换,不需要通过映射表。(映射表是为了分开进程在内存中不同的位置)同一进程的内部线程都在同一空间下。
  • 多个线程不能共同使用一个栈,跳转会出现错误,所以每个线程都有自己的栈。切换线程的时候要切换栈。切换栈也是通过修改esp寄存器就可以了。下面顺序执行ABCD,104,204,304,404是位置


  • 放个TCB(记录线程的一些信息,如果栈的位置等)和PCB的关系图片


2.用户级线程也是就采用yield()进行切换,这个函数可以由我们自己的代码控制,不用到内核中。

也就是说用户级线程可以自己实现调度,不需要内核。

3.优缺点

优点

  • 线程的调度不需要内核直接参与,控制简单。
  • 可以在不支持线程的操作系统中实现。
  • 同一进程中只能同时有一个线程在运行,如果有一个线程使用了系统调用而阻塞,那么整个进程都会被挂起,可以节约更多的系统资源。

缺点

  • 一个用户级线程的阻塞将会引起整个进程的阻塞。
  • 用户级线程不能利用系统的多核处理,仅有一个用户级线程可以被执行。会浪费多核的价值

三:内核级线程

1.和用户级线程的区别

我们知道了用户级线程是通过yield()来实现切换的。切换的时候切换tcb,tcb有关联着用户栈。内核级线程切换tcb的时候不光到切换用户栈还要切换核心栈。
用户线程通过中断,可以变成内核线程。内核级线程也可以变成用户级线程

2.内核级别线程和用户级线程的切换
  • 用户级线程向核心级线程切换(INT):硬件分配核心栈空间并压入SS、SP、EFLAGS、源PC、源CS。保存了用户级线程栈的位置、在用户空间执行到的位置。
  • 核心级线程向用户级线程切换(IRET):从核心栈中取出用户栈的SS、SP。跳到用户栈。并设PC(线程上次执行的位置),EFLAGS(线程上次执行到的状态)、CS(段基址)

    例子:线程一开始在用户态,然后在用户栈压入104、204。int 0x80通过中断进入内核,保存用户栈位置SS、SP。保存用户级线程跳过来的状态EFLAGS。保存返回地址304。保存用户线程代码段的基地址1000。从核心态返回的时候直接跳到CS:304
3.内核级线程之间的切换

当一个用户级线程需要IO读的时候,通过中断变成核心级线程。然后启动磁盘读,把自己阻塞。其他核心级线程趁机上位。把内核级线程cur变成next


那switch_to是怎样实现的呢?
switch_to仍然是通过TCB找到内核栈指针;然后通过ret切换到某个内核程序;最后再用CS:PC切换到用户程序。

你可能感兴趣的:(进程管理、内核级线程、用户级线程)