LINUX内核的进程调度策略

LINUX内核的进程调度策略

一:调度时机:

内核中:进程自己通过系统调用schedule()或者schedule_timeout()自愿放弃CPU,让CPU调度其他的进程。(schedule_timeout() 可以指定放弃CPU的时间)

1:自愿调度:

用户空间:进程通过系统调用pause()或者nanosleep()而自愿放弃CPU。(nanosleep()也可以指定放弃CPU的时间,此外,Sleep()、Sleep_on()是库函数,不是系统调用,最终也是通过系统调用实现放弃CPU)

2:非自愿调度:

主要发生在系统从内核态返回到用户态时(即从系统空间返回到用户空间),

主要发生在以下几种情况:用户进程进行系统调用返回时(系统调用在系统空间中完成);中断处理完成时(中断处理也是在系统空间);异常处理完成时(异常处理也在系统空间)。

CPU每次从系统空间返回到用户空间时,都会进行一次进程调度。此外,每次时钟中断产生时,发现当前运行进程的时间片超时,也会进行一次进程调度(这也是LINUX系统中各个进程都能够得到执行的原因,否则,如果某个进程不进行系统调用,自身运行有没有异常,又不自愿放弃CPU,系统中又没有中断,则该进程会一直等到时间片用完为止)。也就是说,强制进程调度只发生在用户空间,绝对不会发生在系统空间中。

二:调度方式:“有条件可剥夺”方式。 通过以上调度时机的分析,可见,LINUX内核使用的是“有条件可剥夺”方式的进程调度,当系统运行在系统空间时,是不可已被剥夺的,但是,一旦系统从系统空间返回返回到用户空间时,当前进程就有可能被剥夺CPU的占用权。

三:调度策略:(重点)----“以进程各自的优先级和调度策略“为基础的调度策略。 1:总的调度策略:系统会根据每个进程的优先级和它所采用的调度策略,通过某种算法计算出各个进程的一个运行“权值”,系统每次调度时,就根据这个权值进行调度,权值最高的,最先被调度。但是,这个权值并不是一成不变的,而是随着被执行进程执行的时间而递减,这样,原来权值较低的进程也可以有机会得到执行(保证进程调度的“公正”性)。当所有进程的权值都减小到0时(注意:如果有线程采用下面将要提到的SCHED_FIFO或者,SCHED_RR调度策略,则不可能所有进程的权值都变成0,至少采用这两种调度策略的进程的权值最少会保持1000),系统就会重新计算一次所有进程的权值,再次重复上述调度过程。 ****注:正是因为计算权值的时候,考虑了各个进程的优先级和它所采用的调度策略,所以说,LINUX内核的调度策略是“以进程各自的优先级和调度策略“为基础的调度策略。

2:进程自己的调度策略: 为适应不同的需要,LINUX内核设计了三种不同的进程调度政策:

SCHED_FIFO--------适用于对时间性要求比较强,而且每次运行时所用的时间比较短,实时应用程序适合这种策略。

SCHED_RR-----------“RR”是 Round Robin(轮流)的意思,适合程序比较大,每次运行都需要花费很长时间的进程。

SCHED_OTHER------传统的调度策略,适用于交互式的分时应用 。此外,各个进程可以通过系统调用sched_setscheduler()设置自己的调度策略。

四:通过以上对LINUX进程调度策略的分析,可以得出这种调度策略不能保证实时性要求,所以需要打个所谓的实时补丁包。 但是,在目前不能改变调度策略的情况下,要想提高实时性,可以采取以下措施

1:将CPU时间片划分的小一些。这样做的弊端是进程调度会很频繁,增加因为进程调度而花费的开销。

2:实时进程采用高的优先级(1—99)。

3:实时进程采用SCHED_FIFO的调度策略,但其中要又sleep()等类似的操作

发布了9 篇原创文章 · 获赞 1 · 访问量 6688

猜你喜欢

转载自blog.csdn.net/u014426028/article/details/103401019