linux 操作系统的进程调度(上) -- 进程调度的基本概念

2022-06-05 20:39:41   最后更新: 2022-06-05 20:39:41   访问数量:39




 

操作系统中,每时每刻都有着许许多多的进程在执行着,即便是现在最为强大的多核心 CPU,同时能够执行的任务数量也是相当有限的,那么,在这样资源有限的场景下,这么多进程如何来调度,哪些进程更重要哪些进程的执行可以稍微暂缓呢?这就是操作系统调度器的工作。本文我们就来详细介绍一下。

 

 

众所周知,根据进程的运行状态,进程可以被划分为两类:

 

  1. IO 密集型:频繁 IO,但占用 CPU 的时间不多;
  2. CPU 密集型:进程执行过程中很少执行 IO 操作,大部分时间都在占用 CPU 资源执行计算任务。

 

我们常见的与用户发生交互的程序一般都是 IO 密集型进程,这类进程很少占用 CPU,大部分时间在等待着用户进行操作或者 IO 操作完成,但一旦用户进行了操作,CPU 就必须立即响应,否则就会直接影响到用户的体验,想象一下,你移动了一下鼠标,CPU 由于被 CPU 密集型进程占用着,而让你的鼠标在屏幕上一顿一顿地移动,这显然太过于糟糕。所以 IO 密集型进程的优先级却要高于 CPU 密集型进程。

 

而非交互式进程通常是需要密集计算的 CPU 密集型进程,这类进程由于不与用户交互,从而在用户无感知的情况下运行,对响应时间的要求也就没有 IO 密集型进程那么高,所以在操作系统中,他们就属于低优先级进程。

 

 

在操作系统中,同时运行着那么多进程,操作系统是如何确定每个进程的优先级呢?

 

在 Linux 操作系统中,系统会为每个进程打一个分,这个分就是 PR 值,它是 Priority 的前两个字母。

 

通过 PR 值的范围,linux 换分出了两类进程:

 

  1. 实时进程 -- PR 值在 0 到 99 之间,PR 值越大,优先级越高;
  2. 普通进程 -- PR 值在 100 到 139 之间,PR 值越小,优先级越高。

 

但有时,用户可能会不认可操作系统的优先级数值,而是想要去手动调整进程的优先级。此时,如果让用户直接干预 PR 值,那风险就显得很大。Linux 为用户层设计了一个 Nice 值,翻译为“谦让值”。

 

PR = PR + Nice

 

Nice 值取值为 -20 到 19,它的存在让用户得以在一定范围内对 PR 值进行调整。

 

由于用户能够干预的一般都是普通进程,因此,Nice 值为 0 表示不干预,负值表示增加优先级,正值表示降低优先级。

 

 

 

 

在调度进程时,操作系统有两种选择:

 

  1. 协作式调度 -- 进程一旦被调度运行,除非他运行结束或主动释放 CPU,否则它将一直占用 CPU。
  2. 抢占式调度 -- 进程占用 CPU 的期间可以被其他进程夺走对 CPU 的占用,由操作系统决定每个进程占用 CPU 多久。

 

显然,协作式调度的方式下,执行中的进程一旦想要让出 CPU,它必须自己去保存自己的工作状态,而操作系统所需要做的仅仅是在一个任务让出 CPU 后决定让谁来接替它,这样的设计方式简单而高效,但缺陷也显而易见,一旦一个不那么重要的进程长期霸占 CPU,其他进程都将得不到执行。

 

而抢占式调度的模式下,操作系统尽管增加了进程切换的开销以及调度算法设计的复杂度,但却可以更加灵活地分配 CPU 的时间资源,所以常见的操作系统一般都采用抢占式调度的策略。

 

 

调度器设计中需要考虑两个重要指标:

 

  1. 周转时间 -- 进程任务从开始排队等待 CPU 资源直到任务完成的时间差。
  2. 响应时间 -- 进程任务从开始排队等待 CPU 资源直到被调度使用 CPU 的时间差。

 

可以设想,众多等待执行的进程就像是在超市中等待结账的顾客,对他们而言,“响应时间”相当于排队的时间,“周转时间”相当于从开始排队完成结账的时间。对于这些顾客而言,缩短周转时间是他们的核心诉求,但对于超市来说,综合考虑不同顾客对于排队时长的特殊诉求,合理安排所有顾客的排队顺序,才能够降低系统周转时间,拥有良好的用户体验。

 

综合来说,操作系统的调度原则是:

 

  1. 相较于普通进程,实时进程需要更加优先调度;
  2. IO 密集型进程需要频繁调度,以保证缩短响应时间,但单次调度中的执行时长可以缩短,也就是尽量少分配时间片,从而保证系统周转时间的缩短;
  3. CPU 密集型进程可以减少调度频率,进而保障 IO 密集型进程的响应,但单次调度中,CPU 密集型进程可以延长执行时长,也就是适当分配较长的时间片,从而提升 CPU 资源的使用率,缩短整体周转时间。

 

 

本文,我们从操作系统的整体层面,了解了操作系统进程调度的基本概念和设计思想,但我们尚未触及核心部分,到底 linux 系统中的调度器是如何设计的,又有着怎样的历史沿革,出现了哪些算法?它们之间又有着哪些优劣?敬请期待下一篇文章的详细讲解。

 

 

欢迎关注微信公众号,以技术为主,涉及历史、人文等多领域的学习与感悟,每周三到七篇推文,只有全部原创,只有干货没有鸡汤

 

linux 使用及配置相关






操作系统      linux      进程      进程调度     


京ICP备15018585号