什么!这些算法都不会?还学什么操作系统

此篇文章带你梳理一下操作系统中都出现过哪些算法 

进程和线程管理中的算法

进程和线程在调度时候出现过很多算法,这些算法的设计背景是 当一个计算机是多道程序设计系统时,会频繁的有很多进程或者线程来同时竞争 CPU 时间片 。那么如何选择合适的进程/线程运行是一项艺术。当两个或两个以上的进程/线程处于就绪状态时,就会发生这种情况。如果只有一个 CPU 可用,那么必须选择接下来哪个进程/线程可以运行。操作系统中有一个叫做  调度程序(scheduler)  的角色存在,它就是做这件事儿的,调度程序使用的算法叫做  调度算法(scheduling algorithm)  。

调度算法分类

针对不同的操作系统环境,也有不同的算法分类,操作系统主要分为下面这几种

  • 批处理操作系统

  • 交互式操作系统

  • 实时操作系统

下面我们分别来看一下这些操作系统中的算法。

批处理操作系统中的算法

设计目标

批处理系统 广泛应用于商业领域,比如用来处理工资单、存货清单、账目收入、账目支出、利息计算、索赔处理和其他周期性作业。在批处理系统中,一般会选择使用 非抢占式算法 或者 周期性比较长 的 抢占式算法 。这种方法可以减少线程切换因此能够提升性能。

在 交互式用户环境 中,因为为了用户体验,所以会避免长时间占用进程,所以需要 抢占式算法 。由于某个进程出现错误也有可能无限期的排斥其他所有进程。为了避免这种情况,抢占式也是必须的。

在 实时系统 中,抢占式不是必须的,因为进程知道自己可能运行不了很长时间,通常很快的做完自己的工作并挂起。

关键指标

通常有 三个指标 来衡量系统工作状态: 吞吐量、周转时间和 CPU 利用率

  • 吞吐量(throughout)  是系统每小时完成的作业数量。综合考虑,每小时完成 50 个工作要比每小时完成 40 个工作好。

  • 周转时间(Turnaround time)  是一种平均时间,它指的是从一个批处理提交开始直到作业完成时刻为止的平均时间。该数据度量了用户要得到输出所需的平均等待时间。周转时间越小越好。

  • CPU 利用率(CPU utilization)   通常作为批处理系统上的指标。即使如此,CPU 利用率也不是一个好的度量指标,真正有价值的衡量指标是系统每小时可以完成多少作业(吞吐量),以及完成作业需要多长时间(周转时间)。

下面我们就来认识一下批处理中的算法。

先来先服务

很像是先到先得。。。它是一种非抢占式的算法。此算法将按照请求顺序为进程分配 CPU。最基本的,会有一个就绪进程的等待队列。当第一个任务从外部进入系统时,将会立即启动并允许运行任意长的时间。它不会因为运行时间太长而中断。当其他作业进入时,它们排到就绪队列尾部。当正在运行的进程阻塞,处于等待队列的第一个进程就开始运行。当一个阻塞的进程重新处于就绪态时,它会像一个新到达的任务,会排在队列的末尾,即排在所有进程最后。

这个算法的强大之处在于 易于理解 和 编程 ,在这个算法中,一个单链表记录了所有就绪进程。要选取一个进程运行,只要从该队列的头部移走一个进程即可;要添加一个新的作业或者阻塞一个进程,只要把这个作业或进程附加在队列的末尾即可。这是很简单的一种实现。

不过,先来先服务也是有缺点的,那就是没有优先级的关系,试想一下,如果有 100 个 I/O 进程正在排队,第 101 个是一个 CPU 密集型进程,那岂不是需要等 100 个 I/O 进程运行完毕才会等到一个 CPU 密集型进程运行,这在实际情况下根本不可能,所以需要优先级或者抢占式进程的出现来优先选择重要的进程运行。

最短作业优先

批处理中的第二种调度算法是  最短作业优先(Shortest Job First) ,我们假设运行时间已知。例如,一家保险公司,因为每天要做类似的工作,所以人们可以相当精确地预测处理 1000 个索赔的一批作业需要多长时间。当输入队列中有若干个同等重要的作业被启动时,调度程序应使用最短优先作业算法

如上图 a 所示,这里有 4 个作业 A、B、C、D ,运行时间分别为 8、4、4、4 分钟。若按图中的次序运行,则 A 的周转时间为 8 分钟,B 为 12 分钟,C 为 16 分钟,D 为 20 分钟,平均时间内为 14 分钟。

现在考虑使用最短作业优先算法运行 4 个作业,如上图 b 所示,目前的周转时间分别为 4、8、12、20,平均为 11 分钟,可以证明最短作业优先是最优的。考虑有 4 个作业的情况,其运行时间分别为 a、b、c、d。第一个作业在时间 a 结束,第二个在时间 a + b 结束,以此类推。平均周转时间为 (4a + 3b + 2c + d) / 4 。显然 a 对平均值的影响最大,所以 a 应该是最短优先作业,其次是 b,然后是 c ,最后是 d 它就只能影响自己的周转时间了。

需要注意的是,在所有的进程都可以运行的情况下,最短作业优先的算法才是最优的。

最短剩余时间优先

最短作业优先的抢占式版本被称作为  最短剩余时间优先(Shortest Remaining Time Next)  算法。使用这个算法,调度程序总是选择剩余运行时间最短的那个进程运行。当一个新作业到达时,其整个时间同当前进程的剩余时间做比较。如果新的进程比当前运行进程需要更少的时间,当前进程就被挂起,而运行新的进程。这种方式能够使短期作业获得良好的服务。

交互式系统中的调度

交互式系统中在个人计算机、服务器和其他系统中都是很常用的,所以有必要来探讨一下交互式调度

轮询调度

一种最古老、最简单、最公平并且最广泛使用的算法就是  轮询算法(round-robin) 。每个进程都会被分配一个时间段,称为 时间片(quantum) ,在这个时间片内允许进程运行。如果进程在时间片结束前阻塞或结束,则 CPU 立即进行切换。轮询算法比较容易实现。调度程序所做的就是维护一个可运行进程的列表,就像下图中的 a,当一个进程用完时间片后就被移到队列的末尾,就像下图的 b。

时间片轮询调度中唯一有意思的一点就是时间片的长度。从一个进程切换到另一个进程需要一定的时间进行管理处理,包括保存寄存器的值和内存映射、更新不同的表格和列表、清除和重新调入内存高速缓存等。这种切换称作  进程间切换(process switch)  和  上下文切换(context switch) 。

优先级调度

轮询调度假设了所有的进程是同等重要的。但事实情况可能不是这样。例如,在一所大学中的等级制度,首先是院长,然后是教授、秘书、后勤人员,最后是学生。这种将外部情况考虑在内就实现了 优先级调度(priority scheduling)

它的基本思想很明确,每个进程都被赋予一个优先级,优先级高的进程优先运行。

但是也不意味着高优先级的进程能够永远一直运行下去,调度程序会在每个时钟中断期间降低当前运行进程的优先级。如果此操作导致其优先级降低到下一个最高进程的优先级以下,则会发生进程切换。或者,可以为每个进程分配允许运行的最大时间间隔。当时间间隔用完后,下一个高优先级的进程会得到运行的机会。

可以很方便的将一组进程按优先级分成若干类,并且在各个类之间采用优先级调度,而在各类进程的内部采用轮转调度。下面展示了一个四个优先级类的系统

它的调度算法主要描述如下:上面存在优先级为 4 类的可运行进程,首先会按照轮转法为每个进程运行一个时间片,此时不理会较低优先级的进程。若第 4 类进程为空,则按照轮询的方式运行第三类进程。若第 4 类和第 3 类进程都为空,则按照轮转法运行第 2 类进程。如果不对优先级进行调整,则低优先级的进程很容易产生饥饿现象。

最短进程优先

对于批处理系统而言,由于最短作业优先常常伴随着最短响应时间,所以如果能够把它用于交互式进程,那将是非常好的。交互式进程通常遵循下列模式:等待命令、执行命令、等待命令、执行命令。。。如果我们把每个命令的执行都看作一个分离的作业,那么我们可以通过首先运行最短的作业来使响应时间最短。这里唯一的问题是如何从当前可运行进程中找出最短的那一个进程。

一种方式是根据进程过去的行为进行推测,并执行估计运行时间最短的那一个。假设每个终端上每条命令的预估运行时间为  T0 ,现在假设测量到其下一次运行时间为  T1 ,可以用两个值的加权来改进估计时间,即 aT0+ (1- 1)T1 。通过选择 a 的值,可以决定是尽快忘掉老的运行时间,还是在一段长时间内始终记住它们。当 a = 1/2 时,可以得到下面这个序列

可以看到,在三轮过后,T0 在新的估计值中所占比重下降至 1/8。

有时把这种通过当前测量值和先前估计值进行加权平均从而得到下一个估计值的技术称作  老化(aging) 。这种方法会使用很多预测值基于当前值的情况。

保证调度

一种完全不同的调度方法是对用户做出明确的性能保证。一种实际而且容易实现的保证是:若用户工作时有 n 个用户登录,则每个用户将获得 CPU 处理能力的 1/n。类似地,在一个有 n 个进程运行的单用户系统中,若所有的进程都等价,则每个进程将获得 1/n 的 CPU 时间。

彩票调度

对用户进行承诺并在随后兑现承诺是一件好事,不过很难实现。但是有一种既可以给出预测结果而又有一种比较简单的实现方式的算法,就是  彩票调度(lottery scheduling) 算法。

其基本思想是为进程提供各种系统资源(例如 CPU 时间)的彩票。当做出一个调度决策的时候,就随机抽出一张彩票,拥有彩票的进程将获得该资源。在应用到 CPU 调度时,系统可以每秒持有 50 次抽奖,每个中奖者将获得比如 20 毫秒的 CPU 时间作为奖励。

如果希望进程之间协作的话可以交换它们之间的票据。例如,客户端进程给服务器进程发送了一条消息后阻塞,客户端进程可能会把自己所有的票据都交给服务器,来增加下一次服务器运行的机会。当服务完成后,它会把彩票还给客户端让其有机会再次运行。事实上,如果没有客户机,服务器也根本不需要彩票。

可以把彩票理解为 buff,这个 buff 有 15% 的几率能让你产生  速度之靴  的效果。

公平分享调度

到目前为止,我们假设被调度的都是各个进程自身,而不用考虑该进程的拥有者是谁。结果是,如果用户 1 启动了 9 个进程,而用户 2 启动了一个进程,使用轮转或相同

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值