全部博文(1493)
分类:
2012-04-27 08:48:40
原文地址:linux内核的调度机制 作者:JGFNTU
1交互式应用。这种应用,着重于系统的响应速度,当系统中有大量的进程共存时(多用户),要保证每个用户都有可以接受的响应速度,而不感到明显的延迟。当延迟超过150毫秒时,使用者会明显地感觉到。
2.批处理应用。批处理的应用往往都是“后台作业”,对响应速度没有要求,但要考虑到“平均速度”
3.实时应用。这是时间要求最强的,不但要考虑进程执行的平均速度,还要考虑到“即时速度”;不但要考虑响应速度(即从一个事件发生到系统对此作出反应,并开始执行有关程度之间所需的时间),还要考虑有关程序(用记程序)能否在规定时间内执行完。在实时应用中,注重的是对程序执行的“可预测性”。
在设计一个进程调度机制时考虑的问题有:
1.调度的时机:在什么情况下,什么时候调度?【在什么情况下,什么时候,把现在占用CPU的进程换下来。主要在什么位置调用schedule函数】
2. 调度的“政策”policy:根据什么准则挑选下一个进入运行的进程。【从running的进程队列中找出一个进程,来占用CPU,让它运行】。
3.调度的方式:是”可剥夺“(preemptive)还是“不可剥夺”(nonpreemptive)。【一进程主动让出CPU,进程在用户态或是在内核态调用schedule,二是强制剥夺其使用权,在发生中断或是异常或是系统调用之后,从内核态返回到用户态的前夕,由内核调用schedule。】
调度的时机:自愿方式
1.在内核里面,进程可以通过schedule()或是schedule_timeout启动一次调度。在用户空间可以使用调用pause()或是sleep(s)也可以。【这是可见的主动让出的方式。这里指程序员可以看见,程序员编程时主动地让出。】
2.当用户使用open(),read(),write()等N多个涉及到外设的系统调用时,都可能受阻。这时在内核中自愿放弃运行是不可见的。【程序员认为是阻塞了,其实就是让出CPU,进入等待队列,等一个信号或是软中断,或是硬件中断】
不自愿方式,即强制地发生在每次从系统调用返回的前夕,以及每次从中断或是异常处理返回到用户空间的前夕。注意:返回到用户空间是关键性的。这意味着只有在用户空间(当CPU在用户空间运行时)发生的中断 或是异常才会引起调度。(在内核空间发生的中断或是异常,不引起调度。linux2.4)
【以上这种方式不自愿地方式我们习惯地称为“非抢占式内核”也有叫“用户抢占”。其实也就只能叫作“半抢占式内核”或是“有条件抢占”。这种方式是linux2.4的实现方式。在linux2.6中对此进行了修改。大家习惯地称linux2.6内核是“抢占式内核”。】
以下是“抢占式内核”的英文解释。
Kernel preemption is a method used mainly in and where all or most device drivers are run in , whereby the is permitted to
forcibly perform a (ie, preemptively schedule; on behalf of a runnable and higher priority process) on a driver or other part of the kernel during its execution,
rather than wait for the driver or kernel function (such as a ) to complete its execution and return control of the processor to the scheduler.
There are two main benefits to this method in monolithic and hybrid kernels, and answer one of the main criticisms of monolithic kernels from advocates,
which is that;
1 A device driver can enter an infinite loop or other unrecoverable state, crashing the whole system
2 Some drivers and system calls on monolithic kernels are slow to execute, and can't return control of the processor to the scheduler or other program until they complete
execution.
源于:
对“非抢占式内核”、“抢占式内核”的认识过程。
当一看到这两个名词时,第一感觉就是这是一个不同调度方式的内核。在有一些了解之后,发现这种理解有一些问题。“非抢占式内核”说的含义是:不可抢占内核态的调度方式。当然这种方式与内核实现有关,但它的重点是讲一种什么样的调度方式。针对Kernel preemption我们可以翻译为“内核抢占调度模式”,或是“抢占内核调度模式”。
抢占式内核与半抢占式内核的不同
Linux2.4只实现了“有条件抢占式”的调度。它的缺点在于:当进程在内核态时,调度的时机有局限。就是只能在xxx的前夕。例如:当外部来一中断,中断程序过程完后,需要一个用户进程B对此进行进一步的处理(响应IP包数据)。此时进程A正在使用系统调用进入了内核态。那么等到A从系统调用返回之际,内核进行调度,B才有可能运行。假设A的系统调用占用了CPU的时间为T。这个T大于用户要求的响应时间。那这个系统就不够实时。
为了提高linux的实时性。在linux2.6中引入了“Kernel preemption”(内核抢占调度模式)。并很好的解决了这个问题。一句话就是抢占式内核可以在进程处于内核态时,进行抢占。
当然抢占式内核在以下几种情况下不可抢占:
1.当内核运行中断处理程序和异常处理程序时,在linux内核中进程不能抢占中断,在中断例程中不允许进行调度。进程调度函数schedule会对此作出判断,如果是在中断中调用,会打印出出错信息。
2.当进程在内核态运行临界区的代码时,不可抢占。这些临界区被自旋锁spin_lock保护了起来。【但是当进程使用spin_lock时,自己被锁住并自旋时,这时可以调度。】
3. 内核正在进行bottom half(中断的底半部)处理时,不可抢占。【不太懂】
4.内核正在执行调度程序Scheduler时,不可抢占。
5.内核正在对每一个CPU“私有”数据结构操作(per CPU date structures)时,不可抢占。在SMP中,对于Per-cpu数据结构未用spinlocks保护,因为这些数据结构隐含地被保护了。
抢占式内核什么时候,什么位置调用schedule函数?
当中断发生,并完成中断处理时,在返回之前被中断的进程时,可以根据需要进行调度。
抢占式内核为每一个进程的task_struct结构引入了preempt_count变量,称为内核抢占锁。每当进程进入以上五种状态时,preempt_count加1.表示不可抢占。当退出以上五种状态时,preempt_count减1. 每次进行抢占式调度时,先判断preempt_count与0大小,preempt_count<0,表示可抢占。preempt_count>0表示不可抢占。
一系统抢占式的调度器函数:preempt_schedule;preempt_schedule_irq。它们都是调用schedule来完成调度的。
实时操作系统与抢占式内核的关系实时操作系统要求就是对来自外部的请求,要求有及时的处理。及时到什么程度就是实时操作系统呢?这个没有一个明确的定义,因为用户对响应时间的要求各不相同。
我们可以说当在同样的硬件条件下,Linux2.4的实时性不高,或是不如linux2.6的实时性高。那么提高系统的实时性的方法有很多,提高CPU速度,增加CPU核。优化操作系统等。那么 linux在提高系统实时性的重要贡献就是引入了“内核抢占调度模式”。那么我们也可以说linux很好的支持了实时性。
1《Linux可抢占内核的分析》
2《Linux之抢占式内核》
3.linux抢占式内核的研究与实现
4.抢占式内核与非抢占式内核的区别
http://hi.baidu.com/zhangkai008/blog/item/eee55d208f420e49ad34de87.html
5.《linux内核情景分析》