前言

首先来回答一个问题:为什么需要调度?

  1. 有很多task,只有一个CPU,大家都想先运行,如果没有管理人员,起冲突怎么办?
  2. task是无限的,CPU的能力是有限的,有限的资源无法满足无限的需求的时候?
    所以所谓调度,就是针对于资源和需求的管理,是一种资源管理工具,设置规则,让所有task根据规则来决定谁先谁后;

正文开始前首先show一张图介绍本文内容:

1. 概念说明

1.1 task

什么是task?就是需求者!对于Linux来讲,调度的单位是进程,则需求者的具象化就是进程;

TASK状态:

// 基于linux 4.9 路径:/incude/linux/sched.h
/** Task state bitmask. NOTE! These bits are also* encoded in fs/proc/array.c: get_task_state().** We have two separate sets of flags: task->state* is about runnability, while task->exit_state are* about the task exiting. Confusing, but this way* modifying one set can't modify the other one by* mistake.*/
#define TASK_RUNNING        0
#define TASK_INTERRUPTIBLE  1
#define TASK_UNINTERRUPTIBLE    2
#define __TASK_STOPPED      4
#define __TASK_TRACED       8
/* in tsk->exit_state */
#define EXIT_DEAD       16
#define EXIT_ZOMBIE     32
#define EXIT_TRACE      (EXIT_ZOMBIE | EXIT_DEAD)
/* in tsk->state again */
#define TASK_DEAD       64
#define TASK_WAKEKILL       128
#define TASK_WAKING     256
#define TASK_PARKED     512
#define TASK_NOLOAD     1024
#define TASK_NEW        2048
#define TASK_STATE_MAX      4096

1.2 scheduler

什么是scheduler? 就是管理者!在Linux中有scheduler和scheduler_tick两种调度器;

1.3 res

管理的内容是什么?CPU资源,在Linux中CPU资源被划分为时间片,则一个CPU也是一个可拆分的资源;
1. 时间片长短如何决定?根据优先级
2. 时间片的基准来自于哪里?依赖于定时中断,根据系统频率,软件配置HZ,则一个tick为1/HZ,系统中定义HZ为100、250、1000等
- 假设主频为1G,则时间片为us级别

1.3.1 jiffies

记录自系统启动以来产生的tick总数,每次时钟中断产生时,jiffies + 1;

系统中将其初始化为:-300 * HZ(用于检测不对jiffies做溢出检测的缺陷code)
HZ在kernel被初始化为:#define HZ 100 /include/uapi/asm-generic/param.h
如果有指定CONFIG_HZ 则会修改这个tick数,按照这个来计算HZ为100,也就是说一个tick数为10ms
(这里最好还是直接查看机器中的定义:/proc/config.gz中可以看到config_gz=250)对应code中在/kernel/kernel/Kconfig.hz这里配置默认为250HZ(测试修改这里为1000HZ后失败);

2. 调度原理

2.1 一般我们考虑有哪些方式:

如果要管理一个队列,有哪些排队的方式?
类似于:排队管理是动态调整的,比如1号最急,那就直接把1号拍到第一个,再比如10号已经排了半个月了,那就把10号的位置往前提提;

首先我们从原理上考虑有哪些调度算法?

  1. 先进先出的策略,First Come,First Served(FCFS)
  2. 严格按照时间片划分,时间片轮转RR(Round-Robin)
  3. 找到消耗时间最短的任务,SJF(Short Job First,短作业优先)
    1. 就绪状态等待CPU调度的时间长则提升优先级的方式(避免耗时久的任务无法被调度)
  4. 存储多个队列(按照优先级)划分:
    1. 在可抢占的情况下可能存在低优先级的任务永远无法被调度,而且可能出现:现在这个低优先级task和某个高优先级task共享资源,则可能导致无法被释放):

      1. 采用优先级继承,出现上述情况时,直接继承高优先级,处理完成;
      2. 设置临界区优先级上限,则进入临界区的进程都临时使用该优先级;
      3. 禁止中断;
  5. 是否可以被抢占

2.2 衡量指标

name 说明
吞吐量 (Throughput) 每单位时间完成的进程数目
周转时间TT (Turnaround Time) 每个进程从提出请求到运行完成的时间
响应时间RT(Response Time) 从提出请求到第一次回应的时间
CPU利用率(CPU Utilization) CPU做有效工作的时间比例
等待时间(Waiting time) 每个进程在就绪队列(ready queue)中等待的时间

针对于不同的应用场景,上述指标之间是冲突的:

  1. 提高响应速度(时间片短),则会频繁切换,影响吞吐率;
  2. 前台任务和后台任务关注点不同,前台注重响应速度,后台注重吞吐量
  3. 消耗CPU多的和IO受限的:
    1. IO bound,task中存在大量的IO操作,CPU一直在等待IO,IO性能限制,成为block点;
    2. CPU bound,task中存在大量消耗CPU算力的操作,则CPU一直在忙,资源不足,成为block点;

3. linux中的实现

3.1 runqueue

task队列如何管理?每个CPU维护一个结构,将所有的task添加到对应queue中

  1. runqueue:
变量 含义
nr_running 运行队列链表中可运行进程的数量
cpu_load 基于运行队列中进程的平均数量的CPU负载因子
nr_switchs CPU执行进程切换的次数
nr_uninterruptible 先前在运行队列链表中而现在在睡眠状态,且不可打断
nr_iowait 先前在运行队列的链表,现在在等待磁盘IO操作
  1. 如何保证效率:

    1. 每个CPU有一个runqueue;
    2. 对于task-running状态的进程,按照优先级划分为140个list,这样按照优先级直接取最早的就可以了;(对比之前需要遍历所有task,然后计算出最高优先级,效率高很多)
  2. 由于有CPU hotplug的功能,如果现在CPU3 offline的话,该CPU上本来排队的task要如何迁移?
    • CPU HOTPLUG即热插拔,是指在不需要关机的情况下,动态开关其中某一个或者多个core的技术;
    • 对应关闭的core上的runqueue中task_running队列要迁移到其他仍在online状态的CPU上;
    • 排列顺序存在算法补偿;

3.2 策略

  1. 优先级划分:

    1. SCHED_RR:实时进程,按照时间片划分,则添加到可运行队列
    2. SCHED_FIFO:实时进程,调度CPU使用时,会将该进程放在队列中当前位置,即除非有更高优先级打断他,否则他就可以一直执行到task结束;
      1. 实时进程优先级为0~100,也就是说实时进程一定比普通进程优先级高,实时进程永远是running task;
      2. 实时进程如何退出?
        1. 被更高优先级的实时进程抢占;
        2. 自己进入其他状态:
          1. 进入sleep wait:interruptible、uninterruptible
          2. 停止 stop状态
          3. sched_yield,自己放弃掉
          4. 基于RR策略,时间片用完了;
    3. SCHED_NORMAL:普通分时进程
      1. 静态优先级:100~139,值越小,优先级越低;继承自父进程,可通过函数修改(nice、setpriority);

        1. 静态优先级与时间片分配的长短有关:(140-静态优先级)* 系数

          1. 系数与优先级大小有关:100 ~ 120 系数为20 ,120 ~ 140 系数为5;
        2. 动态优先级:根据静态优先级和bonus计算,即TASK在就绪状态等待CPU调度的时间越久,优先级增加越多(bonus 0~10)
          如果按照上述的方式进行,则可能存在一种情况,很多低优先级的case一直得不到调度,所以这里就变得更加复杂了:维护一种活动进程一种过期进程,即用完时间片后加入禁止运行队列;
      2. 当然这里只是描述的处理思路,与实际的实现还要更复杂一些,还要考虑到交互、后台批处理等的差异,这个策略叫做O(1)
      3. 缺陷:
        1. 严格依赖于优先级;
        2. 根据优先级划分时间片,而非根据task的所需时间;

3.2.2 CFS

Linux经过几个版本的更新,O(1)逐步优化为了:完全公平策略(CFS)

  1. 引入virtual runtime的机制(本质为实际CPU耗时),替代原来的优先级;

    1. runtime值,新创建task的runtime值并非是0,而是当前所有task中的min_runtime,这样既可以保证新加入的task优先执行,也可以保证老进程不因为runtime差距过大一直得不到运行;
    2. sleep状态的进程runtime值保持不变?不是,在唤醒时会做一定补偿,这样其他task的值增大后,就会优先处理sleep的task(唤醒后);
    3. runtime值可以无穷小么?系统中定义了最小值,如果比这个小,则无法被抢走CPU;
  2. 采用红黑树的存储,可以满足快速找到;
  3. 优先级计算时间片影响因子,即低优先级的virtual runtime和高优先级的virtual runtime所代表的实际运行时间不同;
  4. 设置一个调度周期时间,则保证所有task在一个周期内有一次调度;
  5. 负载跟踪策略:
    1. PELT:Per-Entity Load Tracking
    2. WALT:Window-Assisted Load Tracking

3.3 图示总结schedule相关关系

CPU负载均衡之调度概念理解相关推荐

  1. LVS负载均衡集群概念

    LVS负载均衡集群概念 一.群集的含义 集群.群集 由多台主机构成,但对外,只表现为一个整体,只提供一个访问入口(域名或IP),相当于一台大型计算机. 1.群集存在的必要 互联网应用中,随着站点对硬件 ...

  2. 负载均衡原理与实践详解 第三篇 服务器负载均衡的基本概念-网络基础

    负载均衡原理与实践详解 第三篇 服务器负载均衡的基本概念-网络基础 系列文章: 负载均衡详解第一篇:负载均衡的需求 负载均衡详解第二篇:服务器负载均衡的基本概念-网络基础 负载均衡详解第三篇:服务器负 ...

  3. Nginx入门简介和反向代理、负载均衡、动静分离理解

    场景 Nginx简介 Nginx ("engine x")是一个高性能的 HTTP 和反向代理服务器 特点是占有内存少,并发能力强,事实上 nginx 的并发能力确实在同类型的网页 ...

  4. 查看linux cpu负载均衡,关于linux内核cpu进程的负载均衡

    2.6内核中进程调度模块的负载均衡行为分为"拉"和"推",推这里不考虑,关于拉均衡有一篇文章特别好,具体出处就不记得了,我当时用的百度快照,那篇文章我认为最精彩 ...

  5. 一文读懂 | CPU负载均衡实现

    在<一文读懂 | 进程怎么绑定 CPU>这篇文章中介绍过,在 Linux 内核中会为每个 CPU 创建一个可运行进程队列,由于每个 CPU 都拥有一个可运行进程队列,那么就有可能会出现每个 ...

  6. linux内核死锁检测机制 | oenhan,Linux内核CPU负载均衡机制 | OenHan

    还是神奇的进程调度问题引发的,参看Linux进程组调度机制分析,组调度机制是看清楚了,发现在重启过程中,很多内核调用栈阻塞在了double_rq_lock函数上,而double_rq_lock则是lo ...

  7. SLB负载均衡的概念

    目录 一:SLB的概念 1.1什么是负载均衡? 1.2负载均衡SLB发展过程 1.3负载均衡的主要作用 二:阿里云负载均衡SLB 2.1阿里云负载均衡SLB的优点 2.2负载均衡SLB应用场景 2.3 ...

  8. linux进程网络均衡,linux多CPU进程负载均衡解析

    在linux中,支持对称smp的处理器模型,在多处理器的情况下,每个处理器都有自己的一个运行队列,这样就存在着分配不均的情况,有的cpu运行队列很多进程,导致一直很忙,有的cpu运行队列可能很少的进程 ...

  9. 简单的几句话让你理解”什么是备份、容灾、集群、负载均衡”

    关于容灾.备份.集群.负载均衡这类概念,很多朋友都容易混淆,到底它们之间有什么区别?今天小编我就给大家分别介绍一下,让大家有个深刻的理解 ! 一.备份概念的理解 "备份"只是将数据 ...

  10. linux在多核处理器上的负载均衡原理

    原文出处:http://donghao.org/uii/ [原理] 现在互联网公司使用的都是多CPU(多核)的服务器了,Linux操作系统会自动把任务分配到不同的处理器上,并尽可能的保持负载均衡.那L ...

最新文章

  1. 网络工程师_记录的一些真题_2005下半年上午
  2. pip安装库包遇到错误:TypeError: expected str, bytes or os.PathLike object, not int 的解决方法
  3. Ring3下实现进程保护,不用hook
  4. 第5章 Python 数字图像处理(DIP) - 图像复原与重建16 - 约束最小二乘方滤波、几何均值滤波
  5. linux--切换ipython解释器到python3
  6. C++ 指向子类的指针转型为指向父类类型指针之后指向的对象地址不变
  7. 二值图像中封闭孔洞的高效填充算法(附源码)。
  8. HDU 1556【线段树区间更新】
  9. flex align-center:center多行垂直方向居中 align-items:center垂直方向单行居中
  10. 《物联网框架ServerSuperIO教程》-19.设备驱动和OPC Client支持mysql、oracle、sqlite、sqlserver的持久化。v3.6.4版本发布...
  11. 编写一个应用程序,给出汉字“你”“我”“他”在Unicode表中的位置。
  12. SecureCRT安装与使用
  13. C语言求解圆周率近似值
  14. 中国电力电子行业前景方向预测及投资规划建议报告2022-2028年版
  15. c语言鸡兔同笼的程序,C语言:鸡兔同笼问题
  16. YOLOv1的pytorch复现版本,博主亲自测试完整复现。
  17. 给交换机console接口设置密码
  18. 【STL MAP】热血格斗场
  19. php组合图片代码,使用php shell命令合并图片的代码
  20. 是地价决定房价还是房价决定地价

热门文章

  1. mysql批量执行sql文件
  2. IFTT-意大利金融交易税
  3. cocos2d-x关于CCTableView的“乱序问题”的理解
  4. .net remoting学习(3) ---配置与服务端广播
  5. Java IO源码目录
  6. 【FPGA-F3】阿里云FAAS平台,极大简化FPGA开发部署流程 1
  7. 国网四川电力应用大数据服务经济社会发展
  8. ubuntu16.xxx安装mysql5.0项目迁移环境搭建
  9. 驱动lx4f120h,头文件配置,没有完全吃透,望指点
  10. 分布式系统设计之DB类(来自深空老大)