Linux进程调度那些事,2024年展望Linux运维原生开发的现状

本文详细介绍了Linux中的实时调度类(如SCHED_FIFO和SCHED_RR)以及CFS(完全公平调度)类别的工作原理,包括调度策略、VRuntime的计算方法和IO密集型/CPU密集型任务的调度处理。同时提到了与实时调度相关的系统调用chrt及其功能。
摘要由CSDN通过智能技术生成
  • Realtime (简称RT) scheduling class主要用在一些耗时很短、对延迟很敏感的task之上,例如IRQ thread。这是一个拥有固定优先级的类别,高优先级的task都会在低优先级的task之前调度。这个类别里实现了两种调度策略:SCHED_FIFO和SCHED_RR。SCHED_FIFO策略会让一个task持续运行直到它放弃占用CPU,例如它block在某个资源上,或者完成了执行。而SCHED_RR(round robin)策略则会对task持续执行的一个时间片限制最大值,如果task持续占用CPU超过这个时长,仍然没有block住(也就是仍然期望继续占用CPU),调度器就会把它放到拥有相同优先级的round-robin队列的尾部,并换一个task进来执行。这些采用实时策略的task可以使用1(最低)到99(最高)的优先级。

  • CFS (completely fair scheduling)class则包含了绝大多数的用户进程。CFS实现了三类调度策略:SCHED_NORMAL,SCHEDULE_BATCH,SCHED_IDLE。采用这三者之中任意一种策略的话,进程就只有在没有任何deadline和realtime class的进程在等待执行的情况下才有机会被调度到(当然缺省来说调度器其实保留了5%的CPU时间专用于CFS task)。scheduler会跟踪各个task的vruntime (virtual runtime),包括那些runnable和blocked状态下的task。一个task的vrtuntime越小,它就越应该优先占用处理器的时间。相应地,CFS会把这些vruntime很低的进程向调度队列的前端移动。

这也是本篇文章的重点。

SCHED_NORMAL调度策略(在user space的名字叫做SCHED_OTHER)是用在Linux环境里运行的绝大多数task上的,例如shell。SCHED_BATCH调度策略则主要用在那些非交互式的任务所需要的批量处理上面,通常这些任务执行中需要一段时间不被打断,因此通常都会在完成所有SCHED_NORMAL工作之后再进行调度切换。SCHED_IDLE调度策略则专用于系统里的低优先级task,他们仅在系统里没有什么需要运行的时候才会执行。尽管实际上说哪怕有其他一些SCHED_NORMAL task,其实SCHED_IDLE task还是会分到一些时间运行的(对于一个nice值为0的task来说大概会有1.4%的时间)。这个调度策略目前用到的很少,有人在试着改进它的工作方式。

  • Idle scheduling class(不要跟SCHED_IDLE的调度策略弄混了)。这是最低优先级的调度类别。就跟Stop class类似,Idle class其实不会用在任何用户进程之上,因此并没有实现什么调度策略。它其实仅仅是用在名为swapper/N(N是CPU序号)的一系列per-CPU kthread上。这些kthreads也被称为"idle thread",用户空间是看不到的。这些线程负责让系统更加省电,主要是通过在没什么事情要做的时候把CPU放到一些deep idle状态来做到的。

在kernel代码里面,scheduling class是用struct sched_class来代表的:

struct sched_class {

const struct sched_class *next;

void (*enqueue_task) (struct rq *rq, struct task_struct *p, int flags);

void (*dequeue_task) (struct rq *rq, struct task_struct *p, int flags);

struct task_struct *(*pick_next_task) (struct rq *rq, struct task_struct *prev,

struct rq_flags *rf);

/* many fields omitted */

};

这个结构里主要放了一些指向class相关实现的函数指针(回调函数),供scheduler core调用,从而能让scheduler核心代码不用包含任何class相关的代码。这些调度类别放在一个按照优先级排序的单项链表里面,第一项是Stop scheduling class(最高优先级),最后一项是Idle class(最低优先级)。

请添加图片描述

CFS(普通进程的调度类)

=============================================================================

设计理念


CFS——完全公平调度,关于的详细的解析这里就不展开来讲了,可以参看《Linux Kernel Development》这本书,这里只调出关于它的一些设计的关键之处,优秀的调度理念来讲。

CFS的出发点基于一个简单的理念:进程调度的效果应该如果系统具备一个理想的完美多任务处理器。在这种系统中,每个进程都能获得 1/n 的处理器时间,n 指可运行的进程数。

同时,在任何可度量时间内,每个进程都可以得到相同多的运行时间。

当然上述的是理想的模型,实现中当然有贴合实际的处理。

CFS的做法是: 允许每个进程运行一段时间,循环轮转,选择运行最少时间(实际上是虚拟的运行时间)的进程

关键问题


  1. 时间片的长度如何分配?

CFS并没有像RR一样固定的分配一个时间片,也不是根据进程的优先级分配长度不一的时间片。而是根据系统当时的负载情况,为每一个任务分配一个比例的CPU处理时间。具体的,CFS没有使用离散的时间片,而是采用目标延迟(target latency),这是每个可执行任务应当运行一次的时间间隔。

根据目标延迟,按比例分配CPU时间。

当然,这个目标延迟有一个默认值、最小值,当然随着系统负载的提高,这个目标延迟还可以延长。

  1. 优先级如何影响调度?

CFS没有直接分配优先级(对于普通进程而言)。它通过每个任务的虚拟运行时间(vruntime),进而每个任务运行多久,虚拟运行时间和基于**优先级(nice值)**的衰减因子有关。

进程的优先级是通过对它的nice值(取值范围-20到+19)加上120而得到的。

进程的优先级主要是用来调整进程的权重(weight,会影响vruntime增加速率)的,进而会影响到进程的vruntime。nice值越低,优先级就越高。task的权重因此也会更加高一些,相应的vruntime则会在task执行时增长得更加缓慢。

  1. 如何调度IO密集型、CPU密集型任务?

首先,IO密集型任务需要更频繁的调度,但是每次需要的CPU时间片很短;而CPU密集型任务需要相对更长的时间片,但是调度频率可以较低。

如何解决?显然IO型任务的vruntime是比较低的(假定nice值都相同),所以它因为vruntime很小,很快可以得到再次调度,而CPU密集型任务只要得到处理器资源,就可以用完分配给它的时间片。

所以,IO型任务的vruntime总是偏小,所以”优先级“比CPU型任务更高,总是可以得到及时调度。

不过,精妙的是,这样的优先级既不是用户显式指定的,也不是os通过某种方式动态调整,完全是根据进程的自身的行为动态调整的。

  1. 可运行的进程以何种数据结构组织?

在CFS调度类中,所有可执行的任务都放置在红黑树中,键值正是 vruntime,如下图。

请添加图片描述

当进程从可执态到阻塞态时,会从红黑树中删除,当再次可调度的时候,又会加入红黑树。

实时进程的调度类

========================================================================

实时进程的调度类优先级比CFS调度类要高。

Linux提供两种实时调度策略,FIFO和RR。关于这两种调度策略比较简单,教科书上也都有就不讲了。

与调度相关的系统调用

==========================================================================

chrt


chrt --help

songyangji@SongyangJi-Ubuntu-DeskStop:~$ chrt --help

显示或更改某个进程的实时调度属性。

设置策略:

chrt [选项] <优先级> <命令> [<参数>…]

chrt [选项] --pid <优先级>

获取策略

chrt [选项] -p

策略选项:

-b, --batch 将策略设置为 SCHED_BATCH

-d, --deadline 将策略设置为 SCHED_DEADLINE

-f, --fifo 将策略设置为 SCHED_FIFO

-i, --idle 将策略设置为 SCHED_IDLE

-o, --other 将策略设置为 SCHED_OTHER

-r, --rr 将策略设置为 SCHED_RR (默认)

调度选项:

-R, --reset-on-fork 为 FIFO 或 RR 设置 SCHED_RESET_ON_FORK

-T, --sched-runtime DEADLINE 的运行时参数

-P, --sched-period DEADLINE 的周期参数

-D, --sched-deadline DEADLINE 的截止时间参数

其他选项:

-a, --all-tasks 对指定 pid 的所有任务(线程) 操作

-m, --max 显示最小和最大有效优先级

-p, --pid 对指定且存在的 pid 操作

-v, --verbose 显示状态信息

-h, --help display this help

-V, --version display version

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Linux运维工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Linux运维知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加VX:vip1024b (备注Linux运维获取)
img

为了做好运维面试路上的助攻手,特整理了上百道 【运维技术栈面试题集锦】 ,让你面试不慌心不跳,高薪offer怀里抱!

这次整理的面试题,小到shell、MySQL,大到K8s等云原生技术栈,不仅适合运维新人入行面试需要,还适用于想提升进阶跳槽加薪的运维朋友。

本份面试集锦涵盖了

  • 174 道运维工程师面试题
  • 128道k8s面试题
  • 108道shell脚本面试题
  • 200道Linux面试题
  • 51道docker面试题
  • 35道Jenkis面试题
  • 78道MongoDB面试题
  • 17道ansible面试题
  • 60道dubbo面试题
  • 53道kafka面试
  • 18道mysql面试题
  • 40道nginx面试题
  • 77道redis面试题
  • 28道zookeeper

总计 1000+ 道面试题, 内容 又全含金量又高

  • 174道运维工程师面试题

1、什么是运维?

2、在工作中,运维人员经常需要跟运营人员打交道,请问运营人员是做什么工作的?

3、现在给你三百台服务器,你怎么对他们进行管理?

4、简述raid0 raid1raid5二种工作模式的工作原理及特点

5、LVS、Nginx、HAproxy有什么区别?工作中你怎么选择?

6、Squid、Varinsh和Nginx有什么区别,工作中你怎么选择?

7、Tomcat和Resin有什么区别,工作中你怎么选择?

8、什么是中间件?什么是jdk?

9、讲述一下Tomcat8005、8009、8080三个端口的含义?

10、什么叫CDN?

11、什么叫网站灰度发布?

12、简述DNS进行域名解析的过程?

13、RabbitMQ是什么东西?

14、讲一下Keepalived的工作原理?

15、讲述一下LVS三种模式的工作过程?

16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?

17、如何重置mysql root密码?

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

ysql root密码?

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

  • 11
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值