Linux操作系统中进程优先级的分类

384人浏览   2024-05-03 08:47:53

Linux进程分类

当涉及有关调度的问题时, 传统上把进程分类为”I/O受限(I/O-dound)”或”CPU受限(CPU-bound)”.

类型

别名

描述

示例

I/O消耗性

I/O-Bound

频繁进行I/O处理,并花很多时间等待I/O操作完成

键盘等待输入、写磁盘

CPU消耗性

CPU-Bound

花费大量时间进行数字计算,一直占用CPU

大量数学计算

另外一种分法把进程区分成三类:

1.2 linux优先级和分类

操作系统的经典的进程调度算法是基于优先级调度的,优先级的核心思想就是把进程按照优先级进行分类,紧急的进程优先级高,不紧急、不重要的进程优先级低。调度器总是从就绪队列中选择优先级高的进程进行调度,而且优先级高的进程分配时间片会比优先级低的进程长,这体现了一种等级制度。

所以进程优先级代表了进程需要运行的紧急程度和需要更多的运行时间片,linux操作系统最早开始采用nice值来调整进程的优先级。nice值的思想是要对其他进程友好,就需要降低优先级来支持其他进程消耗更多的处理器时间。

nice值的范围是 【-20 , 19】, 默认值是0,nice值越大,优先级反而越低,nice值越小,优先级越高

nice值为-20表明这个进程非常重要,优先级最高;而nice值是19,表明允许其他进程比这个进程优先享有宝贵的CPU资源

内核使用0-139数值表示进程优先级,数值越小,优先级越高。优先级099给实时进程使用,100139给普通进程使用。另外,在用户空间中有一个传统的变量nice,用于映射普通进程的优先级,即100~139

linux按照优先级分为两类进程:

  • 实时进程: 要求最快被响应,比如视频、工业机器控制程序,其优先级为0 ~ 99
  • 非实时进程:即普通进程,我们大部分程序使用的,其优先级为100 ~ 139其还可以细分为两类

交互式进程,需要响应前台请求

后台批处理进程

linux内核中task_struct数据结构中使用了4个成员描述进程的优先级:

1.3 linux权重

linux内核除了使用优先级来表示进程的轻重缓急之外,在实际调度器中还是用了权重的概念来表示进程的优先级,为了计算方便,内核约定nice值为0的进程权重为1024,其他的nice值对应的进程权重值可以通过查表的方式来获取,内核预先计算好了一个表sched_prio_to_weight,表的下标对应Nice值为[-20 ~ 19]

更多Linux内核视频教程文档资料免费领取后台私信【内核】自行获取。

二,Linux调度时机

对于调度器,一个很重要的时调度时机问题,在什么情况下,什么时候发生调度?也就是说在什么情况下,什么时候,把现在占用CPU的进程替换下来,根据进程生命周期的图示,

内核运行调度程序的条件为:

  • 进程从运行状态切换到就绪状态或者等待状态
  • 进程被终结了,就需要从就绪队列中选择下一个进程进行运行

同时哪些场景不能发生调度呢?

  • 在中断处理过程中: 中断处理过程,与硬件密切相关,很难做到中断处理过程进行进程切换
  • 在内核程序临界区:
  • 在原子操作过程中:

非抢占内核和抢占内核:

在不支持内核抢占的系统中,进程/线程一旦运行于内核空间,就可以一直运行,直到他主动放弃或者耗尽时间片为止,这样就会导致非常紧急的进程或线程长时间得不到运行。

例如,当外部来了一个中断,中断程序程序处理完后,需要一个用户程序B对此进程进行进一步处理。而此时进程A正在使用系统调用进入内核态,那么只有等到A从系统调用返回,内核进行调度,B才有可能被运行。假设A的系统调用占用CPU的时间为T,这个T大于用户要求的响应时间,那么这个系统就不够实时

为了提高Linux的实时性。在linux2.6中引入了“Kernel preemption”(内核抢占调度模式)。并很好的解决了这个问题。一句话就是抢占式内核可以在进程处于内核态时,进行抢占。

为保证Linux内核在以上情况下不会被抢占,抢占式内核使用了一个变量preempt_count,称为内核抢占计数。这一变量被设置在进程的thread_info结构中。每当内核要进入以上几种状态时,变量preempt_count就加1,指示内核不允许抢占。每当内核从以上几种状态退出时,变量preempt_count就减1,同时进行可抢占的判断与调度。

抢占式内核什么时候能发生调度呢?

中断请求被服务历程响应完成,在返回之前被中断的进程时,可以根据需要进行调度

一系统抢占式的调度器函数:preempt_schedule;preempt_schedule_irq。它们都是调用schedule来完成调度的

同样的当时间片用完,进程处于就绪等待状态的时候,会发生调度

在支持内核抢占的系统中,某些特例下是不允许内核抢占的:

内核正进行中断处理。进程调度函数schedule()会对此作出判断,如果是在中断中调用,会打印出错信息。

内核正在进行中断上下文的Bottom Half(中断的底半部)处理。硬件中断返回前会执行软中断,此时仍然处于中断上下文中。

进程正持有spinlock自旋锁、writelock/readlock读写锁等,当持有这些锁时,不应该被抢占,否则由于抢占将导致其他CPU长期不能获得锁而死等。

内核正在执行调度程序Scheduler。抢占的原因就是为了进行新的调度,没有理由将调度程序抢占掉再运行调度程序。

三,linux调度策略

根据什么准则挑选下一个进入运行的进程。从running的进程队列中找出一个进程,来占用CPU,让它运行。

linux调度依赖于调度策略,Linux内核把相同的调度策略抽象成调度类(schedule class)。不同类型的进程采用不同的调度策略,目前Linux内核默认实现了5中调度类,分别是stop、deadline、realtime、CFS和idle,他们分别使用sched_class来实现,并且通过next指针串联在一起

用户空间程序 可以使用调度策略接口函数(sched_setscheduler())来设定用户进程的调度策略,linux内核对于调度策略定义如下:

总结

相关推荐