当前位置: 首页 > news >正文

【Linux 系统】进程优先级

文章目录

  • 前言
  • 1. 进程优先级
  • 2. 根据优先级进行调度
    • 进程调用的其它算法
  • 3. 了解进程切换

前言

本篇文章,小编会和大家分享进程的优先级部分的知识内容,同时包含简单介绍进程的调度算法以及和进程的切换等方面的知识。

如果有哪方面不够正确,希望大家能够指出。

1. 进程优先级

CPU资源是有限的,在单核场景下,CPU资源只有一份,但是一台机器上有多数的进程需要被调度。所以这就决定了进程之间存在着CPU资源的竞争

  • 而操作系统作为软硬件的管理者,就需要让进程进行良性竞争,从而需要确定进程的优先级。(如果一个进程长时间无法得到CPU资源,那么该进程的代码长时间无法推进,这就导致了进程饥饿

Linux在解决这样的问题的时候,就给每一个进程添加了一个属性字段:优先级。Linux在描述进程的时候,采用了一个结构体:struct task_struct。或许在这个进程启动的时候,Linux操作系统就会在struct task_struct中添加进程优先级的描述字段。我们也可以通过ps命令来查看一个进程的优先级属性:

  • 下面是利用ps -l查看终端的相关信息:
    在这里插入图片描述

  • 其中有两个字段是用来描述一个进程的优先级的:

    1. PRI:priority 优先级(数字越小优先级越高
    2. NI:nice 进程优先级的修正数据。范围是[-20, 19]

这就为我们透露出来一个信息:

  • 进程的优先级是可以被修改的。一个进程最终的优先级值的范围就是[60, 99]

    PRI = 80 + NI

  • 但是实际上操作系统是不希望自己内部的优先级被过多进行修改的,所以但是Linux仍然提供了指令例如:nice, renice, top可用于修改一个进程的优先级。同时,修改一个进程的优先级是需要权限的

2. 根据优先级进行调度

  • 那么Linux操作系统是如何根据进程的优先级在进行调用的呢?

操作系统的实现,只会更加复杂不会像我们说的这样简单,我们这里仅仅是谈到优先级影响调用。

  • 结论位图结构 + 哈希。实现趋近于O(1)时间复杂度的调度算法。

我们可以理解,Linux中维护了一个struct runqueue的结构体:

struct runqueue
{struct task_struct **running;struct task_struct **waiting;struct task_struct *run[140];struct task_struct *wait[140];
}
  • 我们会为运行队列维护两个数组,每一个数组存放的就是struct task_struct*的指针,这样指针指向一个进程PCB。而进程的优先级决定着这个进程的PCB的连接位置,例如,一个准备运行的进程优先级为60,那么他就被存储在下标为100的,后面同样的优先级可以采用链表的形式链入数组结构中。

    如果你对数据结构比较敏感,你一定会发现,这不就是哈希桶吗?

    1. [0, 99]的范围是被操作系统内置的一些进程使用的,一般用户的进程是不在这个区间的。
    2. [100, 139]的范围恰好就是一个进程nice值的修改范围[-20, 19]。恰好范围相同

两个队列的的哈希桶

  1. run哈希桶:管理的是运行中的进程,随时准备被CPU进行调度。
  2. wait哈希桶:管理的是等待中的进程。一个刚刚启动的进程/一个刚刚被CPU切换而下的进程(这是一个细节,保证了优先级高的进程不会反复被调度!),链入这个哈希桶中。

但是这样是不够的。当run中的进程都运行结束了,那么我们怎么实现高效的将wait中的进程转化过来进行调度呢?

我们可以采用两个指针:

struct runqueue
{struct task_struct **running;struct task_struct **waiting;
}
  • running:指向run哈希桶。所以我们找到需要运行的队列,就找到running指针即可。
  • waiting:指向wait哈希桶。所以我们找到需要的等待队列,就找到waiting指针即可。
    在这里插入图片描述

所以操作系统是通过running指针来找到需要运行的进程的。那么当执行的进程哈希桶已经为空了,这个时候我们就需要调度wait中等待的进程了。由于waitrun的结构是相同的,所以如果我们想要找到需要调用的进程,其实十分的简单:对两个指针的内容进行交换即可!即swap(&running, &waiting);交换两者的指针只会,那么此时running指针指向的就是刚刚的等待的进程哈希桶。此时,CPU又可以愉快的进行调度了!

  • 那么如何得知run哈希桶已经为空了呢?

    我们可以采用位图的数据结构(这里我们只考虑后面40个优先级的进程)。一个bit位又0/1两种状态,我们利用0:表示当前桶为空;1:表示当前桶不为空char bitset[5]结构中,5个元素(每一个元素8个bit位)的值都为0的时候,我们就可以认为这个整个run已经为空了。

进程调用的其它算法

进程调用还有一些算法。CPU 是擦欧总系统根据某种策略下选择的下一个要运行的进程,调用的基本单位可以是进程/线程,具体取决于操作系统的设计。CPU 调度的主要目标就是提高系统的效率和资源利用率

调度算法原理优点缺点使用场景
先来先服务按照进程就绪的队列顺序进行调度简单易于实现肯恩共导致进程饥饿的问题简单的批处理系统
短作业优先优先调度时间最短的进程。分为抢占式和非抢占式平均等待时间较短难于预知每一个进程的调度时间,可能造成进程饥饿适用于可以准确预估作业的环节
轮转调度每一个进程分配一个固定的时间片公平,所有进程都能得到调度。响应时间短时间片设置过长或者过短都会影响性能适用于交互式系统
优先级调度为每一个进程分配优先级,优先级高先执行可以实现关键任务先处理可能导致优先级低的进程饥饿问题适用于优先级分区的系统
多级反馈队列将进程按优先级分配称为多个队列,每一个队列按照不同的调度策略结合多种调度算法的优点,灵活且适应性强实现复杂适用于多任务混合的型系统

而 Linux

3. 了解进程切换

上面都是谈到了根据进程优先级的调度算法。我们还是很想知道,一个进程是如何被CPU切换下来的。

  • 在Linux中,维护了一个进程的描述结构体:struct task_struct这个结构体中的内容是十分丰富的。其中就包括了一个进程的上下文内容的存储部分。其中就有一个特别重要的字段,记录了进程的所有信息:struct thread_struct thread。这个thread结构体就是专门用于保存进程硬件上下文(尤其是CPU架构相关的寄存器)的。

  • 在CPU中集成了许多寄存器,这些寄存器会保存当前进程的热数据。CPU在进行计算的时候,对于这些热数据就不用再去内存中取用数据而是直接使用CPU中的数据,当完成计算的时候,再写回内存即可。

    简要说说寄存器的角色

进程切换通常被称为 “上下文切换”(Context Switch)

  • 进程切换的过程:

    1. 切换页全局目录

      • CPU有一个寄存器叫CR3(在x86架构下),它指向当前进程的页表(实现虚拟地址到物理地址的转化结构)。页表定义了进程的虚拟地址空间到物理内存的映射。(页表不了解的可以看看小编的进程地址空间)

      • 切换进程时,内核首先会将CR3寄存器的值更新为下一个进程的页全局目录的物理地址(为了配合MMU实现地址转化)。这实际上就是切换了内存空间。从此以后,CPU发出的虚拟地址将由新进程的页表来解析到全新的物理地址。(实际上就将当前执行的进程的代码改变,那么CPU怎么知道刚刚切换来的进程的应该执行哪里呢?rip,rsp寄存器)这一步是进程隔离的核心,确保了进程A无法访问到进程B的内存。

    2. 切换处理器状态

      • 这包括保存(保存被切换下去的进程上下文)和恢复(恢复被切换上来的进程的上下文)所有volatile的寄存器状态。

        • 保存当前状态:将当前进程的所涉及到的寄存器(通用寄存器……)的内容/值,拿到自己内核空间,并最终更新task_struct->thread中。(自己的进程上下文就被保存在了自己的struct task_struct中)

        • 恢复下一个状态:从下一个进程的task_struct->thread中取出它上次保存的所有寄存器值,并将其加载到对应的CPU寄存器中。特别重要的是栈指针寄存器rsp和指令指针寄存器rip(能够找到CPU应该执行那一条代码)。

          加载rsp意味着内核栈切换到了下一个进程的内核栈(rsp指向当前栈的顶部)。加载rip意味着CPU接下来要执行的代码,就是下一个进程上次被切换出去时即将要执行的那条指令(通常是在内核态的调度器代码中)。

  • 简单来说:

    在这里插入图片描述

完。希望这篇文章,能够帮助你/

http://www.dtcms.com/a/431883.html

相关文章:

  • 滕州网站建设企业自己人网站建设
  • 手机做服务器建网站旅游网官网首页
  • 网站内容丰富哪些网站可以做go注释
  • 怎么建立网站快捷方式网站建设与管理 教材
  • 做网站如何保证询盘数量上海到北京飞机几个小时
  • 大模型Agent五大工作模式深度解析
  • 网站制作和设计需要多少钱ie浏览器手机版下载
  • 网站安全监测预警平台建设成效3.常见的网站建设工具有
  • Day05_ARM裸机
  • 机电公司管理小程序|基于微信小程序的机电公司管理小程序设计与实现(源码+数据库+文档)
  • 金融公司网站设计图贵州网站开发制作公司
  • 自己做ppt网站湖北系统建站怎么用
  • 如何自建网站接广告大连网站推广怎么收费
  • 韩雪冬个人网站甘肃建设投资集团控股有限网站
  • 广州建设大马路小学网站三明市住房和城乡建设局网站
  • 嵌入式开发学习日志31——stm32之外部中断与定时器中断的差别与选择
  • 北京建站者公司网站模板的好处
  • 潍坊网站建设 诸城自己做网站赚钱
  • 使用Netty解析WebSocket协议
  • 织梦做淘宝客网站视频教程wordpress 输出
  • 【完整源码+数据集+部署教程】动物图像分割系统: yolov8-seg-C2f-DySnakeConv
  • 中企动力建设的网站如何修改村网站开设两学一做栏目
  • 那里有网站建设wordpress 手机版主题
  • 长沙培训网站制作无人机东莞网站建设
  • 基于deepseek学习三角函数相关
  • 网站的优化方法archdaily
  • 织梦怎么修改网站标题有关中国文明网联盟网站建设活动方案
  • 简单的网站代码百度云服务器安装wordpress
  • 百度竞价找谁做网站谷歌外贸平台
  • 百度网盘怎样做网站2018网站做外链