进程,进程调度,CPU虚拟化

        本文为操作系统导论CPU资源分配笔记.因作者水平有限,如有错误,恳请不吝赐教.

问题引入:

        假设当前计算机只有一个CPU,而众多应用都想独占CPU资源,如何创造出每个应用都能独占CPU的假象呢?答案是操作系统虚拟化了CPU.

     一.进程

        首先先来了解操作系统提供的一个基本抽象:进程.非正式的说,进程是正在运行的程序.程序是静态的,无生命周期的存在磁盘上的一些指令.而操作系统让这些字节运行起来成为了进程.那么程序如何成为进程呢?操作系统运行程序第一件事从磁盘中读取代码和静态数据,将其加载(load)到内存中某处(涉及分页和交换机制,在以后的文章中会详细介绍),加载到内存后操作系统会程序的运行时栈(run-time stack)分配内存(程序用栈存放局部变量,函数参数和返回地址),操作系统也可能为程序的堆(C用来显式请求动态分配数据)分配内存,同时执行与I/O设置相关的工作.终于操作系统为程序执行打好了舞台.执行最后一项任务:启动程序,通过跳转到main(),OS将CPU控制权转移到新创建的程序,从而程序开始运行.

        了解什么是进程之后我们继续讨论,如何让众多任务共享物理CPU,看起来像是同时运行.一个简单的基本思想是,时分共享,即一个进程运行一段时间,轮换运行.然而问题也随之出现,一我们如何保证运行的进程保持安分高效运行,二操作系统怎样停下当前进程进行切换?

        对于问题一,OS采用受限制操作,即用户模式,与之相对的为内核模式.用户模式中进程收到限制,例如不能向磁盘I/O,否则会导致处理器引发异常,从而终止进程.操作系统在内核模式中运行,代可以执行特权操作.但是用户有时也有执行特权命令的需求,为此,OS提供了系统调用.要执行系统调用,程序必须执行陷阱(trap)指令.该指令陷入内核将特权级提升为内核模式,完成特权操作后,操作系统调用从陷阱返回指令,恢复如初.而陷阱在OS中知道运行哪些代码是由内核在启动时通过设置陷阱表来实现的.当发生硬盘中断等事件后,硬件会找到对应事件的处理代码.

        对于问题二,操作系统停止一个进程听起来很容易,但是进程在运行说明它在使用CPU,即OS未运行,即操作系统无法控制,该怎么办?指望进程是友好进程自行归还控制权嘛?未免太过善良,在这里我们采用时钟中断.时钟设备可以设置几毫秒产生一次中断,发生中断时,当前运行的进程停止,操作系统预先配置好的中断处理程序会运行.OS重新获得CPU控制权,此时它乐意决定是继续运行当前进程,还是切换另一进程(即进程调度,在后文中详细讨论).如果选择前者,即OS执行上下文切换(context switch),保存通用寄存器,程序计数器,以及将当前运行的进程的内核栈指针,然后恢复寄存器,程序计数器,切换内核栈供即将运行进程使用,上下文切换完成.

     二.进程调度

        让我们继续探索,正如上文提到中断后OS进行决策继续哪个进程.如何进行调度决策呢?

        先来看两个指标,周转时间:T周转 = T完成时间-T到达时间,响应时间:T响应 = T首次运行-T到达时间.有了指标后,我们再对操作系统中运行的进程(工作任务)做一些简化假设(之后会一步步去除):

        1每一个工作运行相同时间

        2所有工作同时到达

        3一旦开始,每个工作保持运行到完成

        4所有工作只使用CPU,不进行I/O

        5操作系统知道每个工作的运行时间

        一先到先服务(first come first served)

        想象三个进程A,B,C,因为假设同时到达,A稍微比B早,B稍微比C早,那么根据FCFS,平均周转时间为T = (10+20+30)/3 = 20

   现在我们放宽假设1,那么A先运行100s,周转时间上升为(100+110+120)/3 = 110

这并不是理想的效果.

二.最短任务优先 (SJF)

        如果假设所有任务同时到达的话,SJF的平均周转时间表现最好,(10+20+120)/3 = 50

但是假设2是不切实际的,工作可以随时到达,根据假设3,B和C依然要等到A先完成,平均周转时间为(100+100-10 + 120-10)/3 = 103.33

 

 三.最短完成时间优先(STCF)

        为了解决问题,我们继续放宽假设,即任务不会保持运行到结束,正如前文提到的时钟中断和上下文切换,STCF是抢占式的,每当新工作进入系统时,它会确定剩余工作和新工作中谁的剩余时间最少,然后调度该工作.

平均周转时间为(120+20-10+30-10)/3 = 50

四.轮转(Round-Robin,RR)

        到目前为止似乎情况良好,但考虑到还有个指标响应时间,情况又一下变糟.因为使用者用户的加入,即使周转时间再好,谁也不想输入后等十几秒才能得到反馈,交互性太差.那么如何解决这一问题呢?

        轮转调度思想很简单:RR在一个时间片内运行一个工作,然后切换到运行队列的下一个任务,反复执行知道所有任务完成,当然时间片的长度应为时钟中断周期的倍数.易知RR算法的

响应时间很短.但是时间片的长度并不是越短越好,因为上下文切换是有成本的.RR的问题在于它的周转时间会很大(仔细想想).

五.结合I/O

        我们继续放宽假设4,程序当然要执行I/O的,在执行I/O期间,运行的作业不会使用CPU,它将被阻塞.想象由A,B两项工作,每项工作需要 50ms 的 CPU时间。但是,有一个明显的区别:A 运行 10ms,然后发出 I/O 请求(假设 I/O 每个都需要10ms),而 B 只是使用 CPU 50ms,不执行 I/O。调度程序先运行 A,然后运行 B.一种常见的方法是将 A 的每个 10ms 的子工作视为一项独立的工作。因此,当系统启动 时,它的选择是调度 10ms 的 A,还是 50ms 的 B。对于 STCF,选择是明确的:选择较短的 一个,在这种情况下是 A。然后,A 的工作已完成,只剩下 B,并开始运行。然后提交 A的一个新子工作,它抢占 B 并运行 10ms。这样做可以实现重叠(overlap),一个进程在等 待另一个进程的 I/O 完成时使用 CPU,系统因此得到更好的利用

六.多级反馈队列 (MLFQ)

         最后放宽假设5,因为操作系统对进程一无所知,应该如 何构建调度程序来实现良好的周转时间和响应时间?调度程序如何在运行过程中学习进程的特征,从而做出 更好的调度决策?

先列出MLFQ的规则:      

规则 1:如果 A 的优先级 > B 的优先级,运行 A(不运行 B)。

规则 2:如果 A 的优先级 = B 的优先级,轮转运行 A 和 B。

规则 3:工作进入系统时,放在最高优先级(最上层队列)。

规则 4:一旦工作用完了其在某一层中的时间配额(无论中间主动放弃了多少次

CPU),就降低其优先级(移入低一级队列)。

规则 5:经过一段时间 S,就将系统中所有工作重新加入最高优先级队列。

说明:如果只有规则1,2,那么低优先级的会饿死,规则3,5是为了保护长时间工作的任务有机会使用CPU不被饿死,规则4防止恶意程序或者密集I/O程序独占CPU

        最后,本文讨论了几种常见进程调度算法,希望能重点掌握,感谢观看!

        

        

        

                       

        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值