2021.11.4
进程引入
管理CPU最直观的方式
通过设定PC的值,让CPU反复取指执行
然而在调用IO操作时,会使用硬件调用(磁臂),使用的时间会远远大于其他操作
如果CPU在此期间直接等待,会导致长时间处于闲置状态
于是提出了CPU切换进程,交替进行
并发
在一个CPU上交替的执行多个程序
在程序之间切换时,更改PC的值
而切回是PC再置为53
为了切换成功,单纯设置PC的值是不可行的,还需要保存程序1的现场,即ax,bx等信息,否则会根据程序2中更改成别的值
进程
运行中的程序被称为进程
多进程图像
多进程图像就是多个进程交替推进的样子。对于普通用户来说,打开任务管理器,就可以看到各个进程的样子;对于操作系统来说,操作系统就会创建并维护好各个进程的PCB,保证多进程合理地向前推进。
用户做的就是创建多个进程,而操作系统管理这些进程如何运行
从开机到关机都是多个进程在运行
PCB
Process Control Block:用来记录进程信息的数据结构
进程状态图
进程的调度
FIFO等方式
多进程交替执行
多个进程需要交替执行,则必须同时出现在内存中,这样就出现了问题,如果进程1和进程2中同时都用到相同的地址时,则会互相影响。
进程一对于100进行操作则会导致进程2中代码崩溃
解决办法:限制对于地址100的读写
映射表
进程都会采用映射表去找到需要的地址
不同的进程拥有不同的,完全分离的映射表
这样一来就不会互相影响
多进程合作
进程1和进程2同时向7中填入数据,由于两个进程是交替执行,1在还没有放完时进程2可能就放入,导致文档中的信息既包含1又包含2
生产者消费者问题
经典问题,不写了
用户级线程
进程切换带来的问题,由于进程拥有不同的映射表,所以在进程切换时还需要切换映射表,需要浪费大量的时间
如果能够只切换指令序列,而不切换如映射表的资源,则能节约时间和资源
于是引入了线程
线程
保留了并发的优点,避免了进程切换代价
实质就是映射表不变,只改变PC的值
多线程的优势
如果不采用多线程,则在出现需要耗费大量时间执行(如下载网页)时,已经加载的(如文本)则无法显示在网页中,如此一来用户体验会不好,因此要采用多线程,在下载网页需要花费大量时间时,先切换到文本显示,让用户可以先读取文本,再切换回到下载网页
线程间的切换
通过Yield函数切换线程
Yield切换
在每次跳转,如A中调用B函数时,将b后的地址104压入栈,调用Yield后同理
然而如果像上图一样只使用一个栈,则在B函数调用完成后会进入到404,这显然不合理,因此需要使用两个栈
TCB
由于线程切换需要两个栈,因此在切换时还需要切换栈,采用TCB存放栈的位置即可实现栈的切换
Yield中的JMP是不需要的,因为栈会弹出需要切换的地址,不需要加入JMP进行跳转
用户级多线程的问题
若某个线程进入内核并阻塞,则CPU会切换到别的进程,从而导致该进程中其他线程均不可执行
核心级线程
可以解决上述问题,在一个线程阻塞时会切换到另一个线程去,拥有更好的并发性
核心级线程的优势
发挥多核处理器的优势,线程进入核心,并利用同样的映射
多进程无法使用同一个映射,因此没有该优势
而用户级线程是操作系统无法看到的,因此需要核心级线程才能被操作系统管理,利用到多核的优势
核心级线程的栈
两套栈
用户栈到核心栈
通过中断将用户栈切换到核心栈,并将栈信息及用户线程的信息压入内核栈中,在调用完成返回时出栈并切换到用户栈中
内核中的切换
将esp切换到线程T的栈顶,再逐一出栈,弹出T内核栈中保存的用户栈信息,再切换到用户栈中
????部分包含iret代码,能够切换回用户线程
总的切换
由s的用户线程切换到s的内核线程,而因为要移动esp,所以需要进入到TCB中,再切换到t的TCB,再切换至内核线程,最终进入T的用户线程
两线程的优劣
--p12