当前位置: 首页 > >

操作系统 李治军 进程与线程(二:通过寄存器切换)

发布时间:



操作系统
进程与线程L10 用户级线程L11 内核级线程L12 内核级线程实现L13 操作系统的那棵树



进程与线程

多进程是如何切换的?


L10 用户级线程

什么是线程?


在一个资源下启动多个指令,还可以来回切。但是这不是进程,因为映射表(内存)不需要切换,所以切换代价小。

线程:与映射表不动,只有指令切换,没有内存切换,这就是分治。线程,有时被称为轻量进程(Lightweight Process,LWP),是程序执行流的最小单元。在单个程序中同时运行多个线程完成不同的工作,称为多线程。

如果是顺序程序,就是先下载数据,后面显示文本,,,这样的话,屏幕在一定时间内什么都没有。为什么说是线程不是进程呢。没有切换内存。线程必须要同时触发,并且交替执行。这边是用户态,需要用yield函数实现主动切换。

yield是要能完成切换。切换的时候需要是个什么样子?


将104,204,304等压栈。}相当于ret,所以再往下执行,正常应该范围104,但是里面返回到另外一个线程去了。这是为什么?是因为两个线程共用了一个栈。怎么解决,那就两个栈呗~

切线程,首先把栈切回去,就需要把栈指针保存起来但是要存放到哪里呢,TCB是一个全局的数据结构。寄存器的esp就是栈指针。用于堆栈指针。主要是栈顶指针。


creat就是做出切换的样子。主要是三样东西:申请内存作为TCB,申请内存作为栈,在栈里面压入起始地址。创建的时候就是把要切换的PC指针放到自己的栈中,创建好TCB。将来切换的时候,TCB到栈,在弹出PC指针。


yield在用户态,操作系统完全不能感知到。等到网卡就是需要硬件,需要内核。

浏览器每个标签都是一个线程,所以一个网页卡了,整个浏览器就卡了。所以系统进程切出去了,这个程序就堵塞了。

核心态线程具有更好的并发性。不至于将这个程序堵塞。以上用户态线程只是切换栈,TCB等但是没有接触到内核。用户级线程是核心级线程的基础。schedule是核心级的yield 使用户接触不到的。
总结:用户态线程就是一个栈到两个栈的过程,每个线程拥有自己的栈和TCB,切换就是先切换TCB,后切换栈,栈里面有


L11 内核级线程


进程只有内核态的。
多核必须支持核心级线程,才能发挥作用。MMU就是映射表。
多处理器有多个映射表,多核使用一个映射表。多线程到内核中才能利用多核。并发是同时触发交替执行,并行是同时执行几个线程,共用一套资源。
用户态是核心看不到的所以无法分配硬件资源。


一个TCB关联一套栈。TCB切换一套栈,用户栈和核心栈都要切换。
什么时候会出内核栈。什么时候要进内核,进入内核的方法就是中断(int中断,硬件中断(鼠标点击等))。

ss,sp将内核栈与用户栈相连,之后cs指向100,是段基指针。


Cur,next是当前和下一个的TCB,找到相应的栈。

线程T是用户态的线程,????里面是Iret代码


需要进入到内核才能找到TCB。内核切换的五段论。

next=:就是找到TCB,然后切换内核栈。

申请内存作为TCB, 都是cs:0f,
tcb.esp=krlstack内核栈关联用户栈。esp指向包含中断出口,然后把上面栈东西该弹出去的都弹出去了。然后就开始指向500的代码。


用户级线程想开多少都行,但是核心级不行,因为开的内核资源有限。用户级线程可以改调度,但是核心级是无法修改的。


L12 内核级线程实现


原理就是tcb印发的栈的切换。本讲是代码实现。


fork()是系统调用引起的中断,创建系统调用,创建线程代码。
系统调用号,赋值给eax,然后中断进入内核。INT 0X80执行的时候mov res,%eax。标志寄存器EFLAGS
首先把用户态的数据,把这些数据保存在内核态。

State非0就是意味着阻塞。阻塞后要重新调用。

时间片是不是用光了,用完了也要重新调用。



TSS任务结构段==>KNstack
描述符是指向段的指针。



现在都是改成栈切换了。
接下来是另一个故事,创建一个线程。PCB TCB 。copy内容都是父进程的各种内容。

esp就是sp。C函数调用的顺序和栈顺序相反。


不能用Malloc这是用户态的代码。一页是4K。0X10是内核数据段。

ldt是内存内容。

中断返回时Iret 但是要执行ls-》entry,所以要实现替换

esp是当前栈指针


L13 操作系统的那棵树


Kernel:操作系统的核心。将CPU管理和内存管理合称为Kernel。CPU管理在于进程管理,然后其核心是多进程切换。

认清复杂系统,是这个时代的主题。



执行一会,等待很久








在屏幕交替打印A,B






中断返回进schedule



父进程阻塞,然后开始调用子进程。










友情链接: