正文

线程调度的优先级2009-06-13 14:23:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/xman/44350.html

分享到:

概述

Windows 实现了一个由优先级驱动,抢占式的调度系统,也就是最高优先级的可运行的(就绪状态下的)线程总是先运行。

有一种现象称之为“处理器亲合(processor affinity)”,即线程可能受处理器限制,只运行在那些允许它运行的处理器上。缺省的设置是线程可运行在任何可用的处理器上,用户可以通过使用一个Win32的调度函数修改处理器的“亲合性”。

当一个线程被选择运行,它所运行的时间称之为“时间片”。Windows中断这个线程,去查找是否有别的同优先级或更高优先级的线程正在等待执行,或者这个线程的优先级需要被降低,在这之前这个线程运行的时间长度就是一个“时间片”。不同的线程,其时间片的值可以不同,Window 2000专业版和服务器版的时间片的值是不同的。然而,因为Windows实现的是一种抢占式的调度,一个线程可能未完成其时间片。如果另外有一个更高优先级的线程就绪,正在运行的这个线程就可能在未完成其时间片前被抢占。事实上,一个线程甚至会在未开始其时间片前就被抢占了,而要等待下一次被选择运行。

Windows的没有单独的调度模块或程序,调度的代码是在内核中实现的,广泛分布在内核中那些与调度相关的事件发生的地方。这些负责调度的程序被总称为“内核的调度器”。线程调度发生在DPC/Dispatch级别。

以下这些事件发生时会触发线程调度:

  • 变成就绪状态的线程。例如:一个新创建的线程,或者从等待状态释放出来的线程。
  • 因其时间片结束而离开运行状态的线程,它或者结束了,或者进入等待状态。
  • 线程的优先级改变了,是因为系统调用,或者是Windows自己改变了优先级。
  • 正在运行的线程的处理器亲合性改变了。

在每一个上述情况的衔接点,Windows必须决定下一个运行的线程是哪一个。一旦选择了一个新的线程运行,Windows将对其执行一个上下文转换的操作,即保存正在运行的线程的相关的机器状态,装载另一个线程的状态,开始新线程的执行。

Windows的调度是以线程为粒度调度的。调度的决策被严格限制在以线程为基础,并不考虑这个线程属于哪一个进程。当考虑到进程并不运行,而仅为其线程提供资源和运行的上下文环境时,这种方法就有意义了,例如,进程A10个可运行的线程,进程B2个可运行的线程,而且这12个线程的优先级别相同,那么,每一个线程将会使用1/12CPU时间,而不是将CPU 50%的时间分配给进程A50% 的时间分配给进程B

为了明白线程调度算法,必须首先明白Windows所使用的优先级别。

线程优先级别

Figure 6-12图示:Windows内部使用32个优先级别,从0-31。这些数值被分成以下几类:

  • 16个实时级别(16-31)
  • 15个变化的级别(1-15)
  • 1个系统级别(0), 被保留用作0页线程

线程优先级别是从两个不同的方面来分配的:一个是从Win32应用程序编程接口,另一个是从Windows的内核。

Win32 API的进程在创建时所分配的优先级包括:Real-time, High, Above Normal, Normal, Below Normal, and Idle,进程中各个线程的相关优先级包括:Time-critical, Highest, Above-normal, Normal, Below-normal, Lowest, and Idle。 应用程序默认的优先级为Normal

运行在内核模式的线程可以被用户模式的线程抢占掉,这与线程的状态无关,优先级是决定性因素。

Win32 API中,每个线程的优先级都是它所属的进程的优先级和自己相关的线程优先级二者的组合。从Win32优先级映射到Windows内部数字式的优先级如Figure 6-13图示:

线程的实时优先级

在动态范围内,用户可以可以升高或降低应用程序中线程的优先级。但是,如果要将进程升高到实时范围内,就必须拥有升高调度优先级的权力。如果没有这个权力而企图将一个进程升高到实时优先级,操作不会失败,只是高级级别(High class)将被使用。

很多Windows的重要的内核模式的系统线程是在实时优先级范围内的,如果用户进程花费了过多的时间运行在这个范围内,可能会阻碍了重要的系统功能,如内存管理器、缓冲管理器、本地和网络文件系统,甚至是一些设备驱动程序。因为硬件中断拥有比任何线程都高的优先级,所以不会被阻碍。

在实时范围内的线程性能上有一点不同,当它被抢占时,其线程时间量会被重新设置。

虽然Windows有一套优先级称之为实时,但它们并不是通常意义上定义的实时。因为Windows并没有提供真正的实时操作系统功能,例如确保中断时间间隔,或者是让线程得到一个确保的执行时间。

本文摘自《Windows Internals》第6章《进程、线程和作业》6.5《线程调度》 

阅读(5514) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册