【Linux进程】进程优先级 && Linux 2.6内核进程的调度

目录

前言

1. 进程优先级

2. 并发

3. Linux kernel 2.6 内核调度队列与调度原理

总结


前言

        进程是资源分配的基本单位, 在OS中存在这很多的进程, 那么就必然存在着资源竞争的问题, 操作系统是如何进行资源分配的? 对于多个进程同时运行, 操作系统又是如何调度达到并发呢? 本文将以Linux kernel 2.6为例 , 向大家介绍进程在操作系统中 (OS) 的调度原理;

在这里插入图片描述

1. 进程优先级

      进程优先级是操作系统中用来确定进程获取 CPU 资源的先后顺序的一种机制;

         为什么要排队? 本质是资源不足; 在一台电脑中可能只有一个CPU, 但是可能会同时启动多个进程, 那么进程在分配CPU资源时就需要排队(等待CPU资源);

         对于较为重要的进程, 可以设置高优先级,  高优先级进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整体性能。

使用ps -l查看系统进程:

其中较为重要的信息:

  • UID : 代表执行者的身份
  • PID : 代表这个进程的代号
  • PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
  • PRI :代表这个进程可被执行的优先级,其值越小越早被执行
  • NI :代表这个进程的nice值(在进程PCB中)
     

Linux中进程优先级范围:  60 ~ 99;

Linux中创建进程,默认进程优先级是 80

 在Linux中支持优先级的动态调整,   动态调整的规则:

nice值最小是-20, 超过 -20就统一成 -20;

nice值最大为19, 超过19 统一成19;

 优先级(PRI) 的计算 :  PRI (new) = PRI (old) + nice ;

PRI+ nice值是基于默认值80计算的(不会累计),比如: 先把nice值设为10,那么PRI就会变成90,使用root账户将nice值设为-10,PRI就变成了70 ;

用top命令更改已存在进程的nice:

  • top
  • 进入top后按“r”–>输入进程PID–>输入nice值

 注意: OS只允许普通用户把优先级调低, 不允许把优先级调高, root账户无限制;

 为什么设置限制?

OS在调度时,为了让每一个进程较为均衡得到调度;  如果nice值可以随意乱改, 就会存在用户恶意的将自己的进程优先级调高,导致优先级低的进程长时间得不到CPU资源 ;

需要注意的点是,进程的nice值不是进程的优先级,PR I和 NI 他们不是一个概念,但是进程nice值会影响到进程的优先级变化。可以理解nice值是进程优先级的修正修正数据

 几个较为重要的概念:

  • 竞争性: 系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
  • 独立性:  多进程运行,需要独享各种资源,多进程运行期间互不干扰
  • 并行:  多个进程在多个CPU下分别,同时进行运行,这称之为并行
  • 并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发

2. 并发

 本文的重点是并发 , 先来介绍一下什么是并发? 

        一个进程在被CPU调度时, 并不是一直占用CPU直至运行结束 ,   而是每隔一段时间(这个时间段也叫做时间片) ,它就会被从CPU上被剥离下来 ,   然后会重新放进运行队列等待被调度,如此反复,直到进程运行完毕; CPU每次调度进程时, 都会到运行队列中去取;

        Linux内核支持进程之间CPU资源的抢占,它是一种基于时间片轮转式抢占式内核,时间片非常的短,轮转速度非常快(一秒内进程可能被调度了100次),所以我们很难察觉;

新的问题: 进程在运行时会被从CPU上剥离下来, 那下次调度时, CPU是如何知道进程执行到哪里的呢?

 小方框表示寄存器;

        在CPU当中有很多各种各样的寄存器:eax、ebx、ecx、edx、ss、ds、cs、gs、fs、ebp、esp、eip..

 寄存器的功能有很多,比如记录程序/进程的运行状态(走到那一步);

比如: cpu内:eip:程序计数器;

        进程在运行时会使用这些寄存器,进程会产生各种各样的数据,在寄存器中临时保存 !

        如果有多个进程,各个进程在CPU内形成的临时数据,都是不一样的每个进程运行到哪里,产生的临时数据,叫做进程硬件上下文; 

        在进行轮转切换时会暂时将这个数据存储到进程PCB里;

注意:

        在以前老的Linux中是这样,现在的不是直接保存到PCB,原因是PCB内容太多,太大,但都与PCB有联系,这里只是可以理解为放在PCB当中;本质就是将CPU寄存器当中的数据保存到内存当中;

        CPU寄存器硬件只有一套,进程上下文数据有很多套,比如10个进程有10套上下文数据;

        寄存器 != 寄存器内容

3. Linux kernel 2.6 内核调度队列与调度原理

        有了前边的基础知识补充, 接下来我们介绍一下Linux kernel 2.6 内核调度队列以及基本调度原理;

一个CPU拥有一个runqueue(如果有多个CPU就要考虑进程个数的负载均衡问题)

 下图就是Linux2.6内核中进程队列的数据结构:

 优先级:

  •  普通优先级: 100~ 139
  •  实时优先级: 0~ 99(不关心)

100~139就是我们使用指令看到的40个优先级; 从第100号开始(PRI: 60), 优先级依次向下递减;

 如下图:

 CUP调度队列中的进程是如果直接遍历一遍队列, 然后依次调度进程, 遍历的过程也会造成资源的浪费; 所以在设计时加入了nr_active 和 bitmap[5];

        int整形占4个字节,32个bit位 5 x 32 也就是 160个 bit位 (足够表示140个优先级) ; 利用位图映射可以极大的提高效率; 

         nr_active判断队列是否有进程,bitmap位图映射快速找到进程位置,这样下来轮转一次的效率就会非常高,时间复杂度接近O(1) ;

在操作系统中会维护两个这样的队列 (活动对列 和 过期队列); 

        进程在活动队列并不一定就运行完了,可能是时间片结束了,被调度完之后就会加入到了过期队列;

同时还会维护两个指针:

  • void *active   活动队列
  • void *expired   过期队列

CPU只会执行active指针指向的队列​​​​​​​

         当进程优先级为99的进程正在被执行时,新插入一些优先级较高的进程,这些进程会被插入
到过期队列当中;  (如果直接插入到活动队列,那就会导致优先级较低的队列一直等待,进而引发进程饥饿问题)

        这样一来, 过期队列的进程不断增多, 由于不会插入新的进程,所以它的进程数量一定会越来越少;当active指针指向的活动队列执行完毕,就将两个指针指向的队列进行交换即可

        原本的活动队列执行空了,再来新的进程就插入到这个队列,这个队列会继续作为过期队列
如此循环,最终就完成了进程的调度;

        ​​​​​​​这样的设计方式不仅提高了效率,并且也解决了进程饥饿问题;


总结

         进程是资源分配的基本单位, 在OS中存在这很多的进程, 那么就必然存在着资源竞争的问题, 于是便有了进程优先级来确认进程调度的先后顺序;  但这也可能会伴随着进程饥饿的问题,  而在Linux2.6版本中的进程调度设计很好的解决这些问题; 具有很高的参考学习的价值;  好了以上便是本文的全部内容, 希望对你有所帮助 , 感谢阅读 !

相关推荐

  1. Linux——进程优先级、ACL

    2024-07-10 00:44:04       24 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-10 00:44:04       49 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-10 00:44:04       53 阅读
  3. 在Django里面运行非项目文件

    2024-07-10 00:44:04       42 阅读
  4. Python语言-面向对象

    2024-07-10 00:44:04       53 阅读

热门阅读

  1. 仙人掌中的SNMP检测不到服务器

    2024-07-10 00:44:04       18 阅读
  2. 算法力扣刷题 三十四【71.简化路径】

    2024-07-10 00:44:04       18 阅读
  3. yolov5:Conv类参数量计算

    2024-07-10 00:44:04       23 阅读
  4. GitHub每日最火火火项目(7.9)

    2024-07-10 00:44:04       19 阅读
  5. py基础语法简述

    2024-07-10 00:44:04       16 阅读
  6. 代码随想录算法训练营:20/60

    2024-07-10 00:44:04       19 阅读
  7. 【6-1:全链路压测】

    2024-07-10 00:44:04       19 阅读
  8. 识别色带后执行相应命令

    2024-07-10 00:44:04       17 阅读
  9. QMdiAreaQMdiAreaQMdiAreaQMdiArea

    2024-07-10 00:44:04       20 阅读
  10. Jacoco的覆盖率原理

    2024-07-10 00:44:04       18 阅读