进程与线程
多进程是如何切换的?
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
父进程阻塞,然后开始调用子进程。