操作系统(哈工大视频教程)第11讲到第15讲

第十一讲 内核级线程

MMU(memory manage unit),多核实现真正的并行,既多进程或多线程同时出发,同时进行;并发更多的是多进程或多线程同时出发,交替执行;
在这里插入图片描述
从用户级线程到内核级线程,由一个线程的一个栈变成一个线程的一套栈,既内核级线程要同时对应用户级的栈和内核级的栈,且在切换内核级的栈时,同时切换用户级的栈。
在这里插入图片描述
进入内核的唯一方法是中断(INT中断指令);
在这里插入图片描述
在这里插入图片描述
由线程S切换到线程T的过程:线程 S 从用户栈使用中断指令进入到对应的内核栈,在内核栈使用TCB和switch_to函数,切换到线程T 的内核栈,然后利用中断返回指令 IRET 由 线程T的内核栈切换到用户栈:在这里插入图片描述
在这里插入图片描述
内核线程switch_to的五段论:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

第十二讲 内核级线程的实现

进程由两部分组成:资源和执行序列(既线程);进程又必须需要进入内核,故进程的序列就是内核级序列;
线程的核心是两套栈:用户栈和内核栈,当从线程 1 切换到线程 2 时,从用户的角度来看,直接从用户栈切换到了内核栈,但实际上,是走了五步:从线程 1 的用户栈切换到线程1 的内核栈,再从线程 1 的内核栈到线程1 的TCB,再从线程 1 的TCB 切换到线程 2 的TCB,再从线程 2 的TCB切换到线程 2 的内核栈,再从线程 2 的内核栈切换到线程 2 的用户栈;
在这里插入图片描述
用户程序进入到内核靠的是中断,是系统调用;
在主函数执行时,遇到函数A()的调用,进入函数A 执行,同时将A 的返回地址要入到主函数的栈中,接着在A中执行遇到fork函数,需要进入内核创建线程,执行中断指令,置内核栈
在这里插入图片描述
该开始跳到内核时,要把用户状态的的现场保存起来,保存到内核栈中,以便于返回;中断入口,将内核栈和用户栈相关联;从用户栈跳到内核,在合适的时候调用schedule进行切换,然后中断返回,返回到用户栈
在这里插入图片描述
TSS(task struct segment)
在这里插入图片描述
线程的创建就是要创建出能够切换的线程的样子:
在这里插入图片描述
创建线程的步骤:申请内存,创建TCB,创建内核栈和用户栈,填写两个栈,关联栈和TCB在这里插入图片描述 在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

第十三讲 操作系统的那棵“树”

在这里插入图片描述
操作系统如何从一个点逐渐成为一个复杂系统:
起初,操作系统运转起来,只是顺序的取指执行:
在这里插入图片描述
但后发现,虽然CPU在运转,但运转的不够高效,不够好:
在这里插入图片描述
为了CPU能够更好的运转,需要CPU能够切换,使多个程序能够运行:
**加粗样式**
这种切换类似于函数的跳转,故有了像函数跳转一样的想法,使用栈进行操作:
在这里插入图片描述
但发现使用一个栈和切换的Yield,发现出现了混乱:
在这里插入图片描述
进而有了使用俩个栈和两个用户TCB来实现功能:
在这里插入图片描述
现在实现了用户级的切换,但如何实现内核级的切换:
在这里插入图片描述
进而引入了内核栈的切换:
在这里插入图片描述
到此应将之前的想法付诸实践,交替的打印出A,B,用户代码如下:
main()
{
if(!fork()) {while(1) printf(“A”);}
if(!fork()) {while(1) printf(“A”);}
wait();
}
代码对应的汇编如下:先执行fork,中断执行fork后,返回值赋给res,再将res和 0 进行比较,相等执行 208 的指令序列,不相等顺序执行200 的指令序列
在这里插入图片描述
那么 INT 的中断指令是如何执行的?INT 中断指令是进程从用户态进入内核,随后执行了system_call
在这里插入图片描述
执行system_call,就需要执行sys_fork:
在这里插入图片描述
而执行sys_fork,就需要随后跳转到 copy_process,而copy_process就是要在内存中做出一套新的东西:PCB,栈等
在这里插入图片描述
开始返回,执行完copy_process,父进程需要返回,并在中断返回时进行了schedule:
在这里插入图片描述
由于之前的进程没有阻塞,接着执行了下一个fork:
在这里插入图片描述
这样创建好了两个子进程后,主函数还没有阻塞,就接着向下执行, 遇到了wait函数,wait函数将会把主进程改变为阻塞状态,并随之调用schedule函数
在这里插入图片描述
此时的schedule会在就绪对列中选择一个子进程进行执行(既之前创建的子进程),这里只是简单地选择了队首的PCB:
在这里插入图片描述
而选择后,切换的动作是由switch_to完成,这里利用了tss,将CPU内的tss赋给当前进程的tss,并将将要执行的进程的tss赋给CPU的tss,进而完成切换:
在这里插入图片描述
切换后的进程,CPU接着进行取指执行,一直打印A
在这里插入图片描述
接着想要交替的打印出B,则需要进程B执行,这就需要一个调度点,而要有调度,就需要进入内核,要进入内核,就需要有中断:
在这里插入图片描述
这里使用时钟中断:
在这里插入图片描述
在这里插入图片描述
时钟中断后,调用就绪对列中的PCB,使用tss修改CPU的状态
在这里插入图片描述
进程B的执行,同样会有时钟中断,再返回来通过就绪队列切换到进程A
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

第十四将 CPU调度策略

就是如何获得下一个PCB,既当前进程阻塞,CPU需要切换到下一个进程,但是在就绪队列中有不止一个PCB,选择哪一个进程执行,需要调度策略决定
在这里插入图片描述
在这里插入图片描述
CPU的调度方法的评价标准不同,选择不同的调度策略:
在这里插入图片描述
将IO约束型任务的优先级置的高于 CPU约束型任务,这样相当于能让两种任务并行;
折中和综合让操作系统变得复杂,但有效的系统又要求尽量简单
在这里插入图片描述
FCFS(First Come,First Served)
在这里插入图片描述
SJF(Shortest Job First):短作业优先,缩短周转时间
在这里插入图片描述
RR(Round Robin):按时间片来轮转调度,进而满足响应时间
在这里插入图片描述
为了同时满足响应时间和周转时间,将建立两个队列,将需要满足响应时间的任务放到一个队列,比如前台任务,且这个队列使用RR调度,把需要满足周转时间的放到另外一个队列,比如后台任务,且这个任务使用SJF调度,两个队列之间设置优先级,将前台任务的队列的优先级设置的高于后台队列的优先级,进而满足前台队列的响应时间的要求:
在这里插入图片描述
但上述的优先级方法,是将前台任务作为绝对优先,则可能造成低优先级的后台任务不能执行,造成饥饿,故应该有能够动态调整优先级的方法:
在这里插入图片描述
在这里插入图片描述

第十五讲 一个实际的schedule 函数

这里counter同时作为执行的时间片和切换的优先级,在这里有三个循环函数,最外层的循环函数是个死循环,只有循环内部找到可以执行的进程,在循环内部进行跳出循环才行,这里注意其内部只有一个break跳出点;内层的第一个while循环用来找寻此时的就绪队列中的时间片最大的线程,找到后,判断这个进程的时间片是否为 非0,可以执行,若是非 0 的值,则可以在此处通过break跳出外层循环,执行这个时间片所在的线程,否则只能向下执行,执行第二个循环;第二个for循环是用来调整队列中的所有的进程的counter的大小,既相当于将所有的进程的优先级进行调整,这里调整的策略是将时间片当前值的一半加上该进程的原始时间片,作为新的值复制给该进程的时间片counter,这样相当于将还没执行完的进程,既时间片没有用完的进程,既刚才是阻塞状态的进程,既刚才是非就绪状态的进程的优先级进行提高;然后在把所有的进程的优先级改变后,会再次进入到第一个内部循环的,再次从就绪队列中找优先级最大的进程执行;
在这里插入图片描述
counter起到的时间片的作用是通过时钟中断实现的,在调用do_timer函数时,会在counter自减运算后,判读此时是否为零,若为非零,则直接返回,接着执行现在的进程,若已经减到了零,则直接调用schedule函数,切换进程
在这里插入图片描述
counter的优先级作用:在schedule函数的内部循环中的第一个while循环中,在就绪队列中找counter最大的进程,最为要执行的进程,本身就是在把counter作为优先级进行使用 ,相当于把counter作为优先级判断,并且在就绪队列中所有的时间片为零时,就会对所有的优先级进行调整一次,并把阻塞的进程优先级扩大,把就绪队列中的时间片为零的进程的counter的,重新赋成原值:
在这里插入图片描述
counter的动态修改的方法,理论上说,在无限阻塞时间下,其最大值接近2 倍的原始值
CPU调度:一个简单的算法折中了大多数任务的需求,这就是实际工作中的schedule函数
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值