进程的调度概述

进程调度概述
多任务处理机制是需要进行进程调度的本质原因。
cpu的资源是有限的,因此需要使用调度器来为线程分配cpu资源。调度器的主要目的是解决
cpu争用的问题,使得每个进程可以按照一定的规则进行运行。
 
那么如何来分配CPU的运行时间呢?比较传统和朴素的想法就是给每个进程分配优先级,
根据优先级来分配时间片。优先级高的时间片分配的比较多,优先级低的分配的时间片比较少。
由于现在计算机都是多任务并发处理的,所以CPU需要将时间划分为周期,一个周期也就是一段时间。
将这一段时间按照优先级分配给进程。等到所有的进程执行完所有的时间之后,开启下一个周期。
这也是比较经典的进程调度方法。linux2.4使用的是经典的调度策略,
到linux2.6则使用O(1)调度策略的主要思想都是一致的。
 
总结上面经典方法涉及到以下关键点:
1 给进程分配优先级别。
2 时间片如何分配
3 将分配好的进程组织起来进行存放。
4 在组织好的进程内部选择最优的进程。
 
进程优先级
优先级与进程类别有关,进程分为以下几类:
1 硬实时进程,此类进行对时间的要求比较高,必须在规定的时间内进行相应
2 软实时进程,对时间要求也很到,但及时不响应,也不会世界末日。
3 普通进程(IO密集形和计算密集形式)
 
其中硬实时进程和软实时进程的优先级比较高(0-99)
普通进程的优先级(100-140)
实时进程的优先级要高于普通进程的优先级。
 
nice值:提供给用户态可以动态修改的值,nice值越大,优先级越低。
nice值越小,优先级越高。
(-20-19)nice值和进程优先级具有一定的对应关系。代码定义如下所示:
#define MAX_USER_RT_PRIO    100
#define MAX_RT_PRIO        MAX_USER_RT_PRIO
#define MAX_PRIO        (MAX_RT_PRIO + 40)
#define USER_PRIO(p)        ((p)-MAX_RT_PRIO)
#define MAX_USER_PRIO        (USER_PRIO(MAX_PRIO))
#define NICE_TO_PRIO(nice)    (MAX_RT_PRIO + (nice) + 20)
 
时间片的分配 
时间片是关键的资源,分配多少时间片意味着一个进程可以在一个周期内执行多长时间。
#define HZ   1000    
#define DEF_TIMESLICE  (100 * HZ / 1000)
#define SCALE_PRIO(x, prio) \
    max(x * (MAX_PRIO - prio) / (MAX_USER_PRIO/2), MIN_TIMESLICE)
 
static unsigned int task_timeslice(task_t *p)
{
    if (p->static_prio < NICE_TO_PRIO(0))
        return SCALE_PRIO(DEF_TIMESLICE*4, p->static_prio);
    else
        return SCALE_PRIO(DEF_TIMESLICE, p->static_prio);
}

 

上面就是时间计算函数,主要跟nice值有关,因此可以判断,时间片的分配和nice值有很大的关系。nice值越大可以分配的
时间片也就越多。
 
普通进程有一类交互式进程,交互式进程要求计算机快速反应。这样用户的体验比较好。
对于交互式进程,需要优先执行。方法就是对nice值进行动态调整,调整的依据就是判断进程是不是
sleep的时间比较长,如果时间长,时间片也就用的少,时间片用的少则会提高nice值,来提高优先级。
 
完全公平调度
经典调度方式以及O(1)调度方式存在一些既有的缺点,导致它的运行并不是很理想。
为了弥补经典调度方式的缺点,完全公平调度算法出现。
完全公平调度算法的核心是:保证所有进程的(运行时间/权重)的值尽可能一致。
完全公平调度算法的核心就是:
vruntime = 实际运行时间 * 1024 / 进程权重                      (公式1)
实际运行时间=调度周期 * 进程权重 / 所有进程总权重(公式2)
将公式2代入到公式1 得到如下结果:
vruntime = 调度周期 * 进程权重 / 所有进程总权重) * 1024 / 进程权重 = 调度周期 * 1024 / 所有进程总权重 
 
vruntime与进程权重无关。1024和所有进程总权重都是常数,唯一的变量是调度周期。
vruntime越小说明进程运行的时间越短,需要给这样的进程更多的运行时间。
 
在完全公平调度算法中,所有的进程内部都有一个变量sched_entity。所有的sched_entity都是通过红黑树进行组织的,这样可以快速地找到要运行的进程。

 

 
参考资料:
调度算法的历史,以及对新的算法的阐述。
看完下面的文章之后了解了完全公平算法。
posted @ 2019-07-29 13:12  周围静地出奇  阅读(342)  评论(0编辑  收藏  举报