linux内核--进程调度

参考:https://blog.51cto.com/u_15185954/3034377

1. 调度策略

(1)基于时间片轮转

  linux采取单凭经验的方法,即选择尽可能长,同时能够保持良好响应时间的一个时间片(既不能太长也不能太短)。

(2)基于优先级抢占

        进程优先级是动态的,基于运行情况实时做调整

   进程的抢占:linux进程是抢占式的,当进程进入TASK_RUNNING状态时,如果他的动态优先级大于当前正在运行的进程,则终止当前进程,执行新的进程;或者在时间片到期时被抢占。

(3)进程分类

    方式1:

   I/O受限

  CPU受限

       方式2:

  交互式进程,shell窗口

  批处理进程,编译

    实时进程,机器人控制程序

(4)与调度相关的系统调用

  nice  改变一个普通进程的静态优先级

  ......

 

2. 调度算法

 linux2.6 在固定时间内选择要运行的的进程,很好的处理了与处理器数量的关系,每个cpu拥有自己的可运行进程队列,较好的解决了区分交互式进程的批处理进程的问题。

(1)调度分类

  SCHED_FIFO 先进先出的实时进程

  SCHED_RR 时间片轮转的实时进程

  SCHED_NORMAL 普通的分时进程

(2)普通进程的调度

  100-139为普通进程的静态优先级,值越大静态优先级越低。

  新进程总是继承父进程的静态优先级。

  时间片由优先级决定,静态优先级越高基本时间片越长。

  动态优先级范围100-139,是调度程序在选择新进程来运行时使用的数,与静态优先级的关系:动态 = max(100,min(静态 - bonus + 5139))

  平均随眠时间是进程随眠状态所消耗的平均纳秒数,调度程序通过平均随便时间判断一个进程是交互式进程还是批处理进程

  活动和过期进程,活动进程:还没有用完他们的时间片,因此允许他们运行;过期进程:已经用完时间片,并因此被进制运行,直到所有活动进程都过期

(3)实时进程的调度

  实时进程优先级1-99

  调度成都总是让优先级高的进程先运行,实时进程总是被当成活动进程

  对于具有相同最高优先级的几个实时进程,调度程序选择第一个出现在运行队列相应链表中的进程

  实时进程被另一个进程取代的情况:

  (1)被更高优先级的实时进程取代

  (2)进程执行了阻塞操作进入随眠

  (3)进程停止

  (4)进程通过系统调用自愿放弃CPU

  (5)进程是基于时间片轮转的实时进程,而且用完了他的时间片

 

3.调度程序所使用的数据结构

 进程链表连接所有的进程描述符,运行队列链表连接所有的可运行进程

(1)runqueue

  每个cpu对应一个runquere变量,this_rq()产生本地cpu运行队列地址,cpu_rq(n)产生索引为n的cpu运行队列地址

  runquere各字段含义

  

 

 

  可运行进程属于且只属于一个可运行队列,只能在拥有该运行队列的cpu上面运行,可运行队列可从一个运行队列迁移到另一个可运行队列

  arrays包含两个prio_array_t结构的数组,每个数据结构都表示一个可运行队列的集合,并包含140个双向链表头。

  

 

   活动进程与过期进程周期性的发生变化,只需要修改active和expired的指向即可。

(2)进程描述符

  task_struct

  

 

   

 (3)调度程序所使用的函数

  a、scheduler_tick()维持当前最新的time_slice计数器

  b、try_to_wake_up函数   通过把进程状态设置为TASK_RUNNING,并把进程插入本地CPU运行队列来唤醒随眠或停止的进程

    c、recalc_task_prio函数 更新进程的平均随眠时间和动态优先级

  d、schedule函数。实现调度程序,可以采用直接调用或延迟调用   

    进程切换之前执行的操作

    进程切换时所执行的操作

    进程切换后所执行的操作

 

3. 多处理器系统中运行队列的平衡

(1)分类

 a、标准的多处理器体系结构:这些芯片共有的ARM芯片集被所有CPU共有

 b、超线程:一个超线程的物理CPU被Linux看做几个不同的逻辑CPU

 c、NUMA :把CPU和RAM以本地节点为单位分组

(2)调度域

     实际上是一个cpu集合,工作量由内核保持平衡

(3)rebalance_tick函数 

  确定运行队列中的进程数,并更新运行队列的平均工作量

(4)load_balance函数

  检查调度域是否处于严重的不平衡状态

(5)move_tasks函数

  把进程从源运行队列迁移到本地运行队列

 

 

4. 与调度相关的系统调用

(1)nice系统调用

  允许进程改变他们的基本优先级

(2)getpriority和setpriority

  作用于给定组中所有进程的基本优先级

(3)sched_getaffinity和sched_setaffinity

  分别返回和设置cpu进程亲和力掩码,也就是允许执行进程的CPU的位掩码

(4)与实时进程相关的系统调用

  查询和设置进程当前所用的调度策略

(5)sched_getparam和sched_setparam系统调用

  设置和查询进程检索调度参数

(6)sched_yield

  进程在不被挂起的情况下自愿放弃cpu

(7)sched_get_priority_min和sched_get_priority_max

  返回最大和最小实时静态优先级的值

(8)sched_rr_get_interval

  修改某个进程的轮转时间片

 

posted on 2021-09-10 09:59  world_hello!!!!  阅读(266)  评论(0编辑  收藏  举报

导航