优先级是线程调度的重要依据。优先级高的线程,永远先获得CPU的青睐。当然啦,操作系统会视情况调整各个线程的优先级。例如前台线程的优先级应该调高一些,后台线程的优先级应该调低一些。
线程的优先级范围从0(最低)到31(最高)。当你产生线程时,并不是直接以数值指定其优先级,而是采用两个步骤。第一个步骤是指定“优先级等级(Priority Class)”给进程,第二步骤是指定“相对优先级”给该进程所拥有的线程。表1是对优先级等级的描述,其中的代码在CreateProcess的dwCreationFlags参数中指定。如果你不指定,系统默认给的是NORMAL_PRIORITY_CLASS,除非父进程是IDLE_PRIORITY_CLASS(那么子进程也会是IDLE_PRIORITY_CLASS)。
等 级 | 代 码 | 优 先 级 值 |
idle | IDLE_PRIORITY_CLASS | 4 |
normal | NORMAL_PRIORITY_CLASS | 9(前台)或7(后台) |
high | HIGH_PRIORITY_CLASS | 13 |
realtime | REALTIME_PRIORITY_CLASS | 24 |
表 1 Win32 线程的优先级等级划分 |
■ “idle”等级只有在CPU时间将被浪费掉时(也就是idle time)才执行。该等级最适合于系统监视软件,或屏幕保护软件。
■ “normal”是默认等级。系统可以动态改变优先级,但只限于“normal”等级。当进行变成前台,线程优先级提升为9,当进程变成后台时,优先级降低为7。
■ “high”等级是为了满足立即反应的需要,例如使用者按下Ctrl + Esc时立刻把工作管理器(task manager)带出场。
■ “realtime”等级几乎不会被一般的应用程序使用。就连系统中控制鼠标、键盘、驱动器状态重新扫描、Ctrl + Alt + Del等的线程都比“realtime”的优先级还低。这种等使用在“如果不在某个时间范围内被执行的话,数据就要遗失”的情况。这个等级一定得在正确评估之下使用,如果你把这样的等级指定给一般的(并不会常常阻塞的)线程,多任务环境恐怕会瘫痪,因为这个线程有如此高的优先级,其它线程再没有机会被执行。
上述四种等级,每一个等级又映射到某一范围的优先级值,IDLE_最低,NORMAL_次之,HIGH_又次之,REALTIME_最高。在每一个等级之中,你可以使用SetThreadPriority设定精确的优先级,并且可以稍高或稍低于该等级的正常值(范围是两个点数)。你可以把SetThreadPriority想象成一种微调操作。
SetThreadPriority 的 参 数 | 微 调 幅 度 |
THREAD_PRIORITY_LOWEST | - 2 |
THREAD_PRIORITY_BELOW_NORMAL | - 1 |
THREAD_PRIORITY_NORMAL | 不变 |
THREAD_PRIORITY_ABOVE_NORMAL | + 1 |
THREAD_PRIORITY_HIGHEST | + 2 |
除了以上五种微调,另外还可以指定两种微调常数:
SetThreadPriority参数 | 面对任何等级的调整结果 | 面对“realtime”等级的调整结果 |
THREAD_PRIORITY_IDLE | 1 | 16 |
THREAD_PRIORITY_TIME_CRITICAL | 15 | 31 |
这些情况可以以表2作为总结。
优先级等级 | idle | lowest | below normal | normal | above normal | highest | time critical |
idle | 1 | 2 | 3 | 4 | 5 | 6 | 15 |
normal(后台) | 1 | 5 | 6 | 7 | 8 | 9 | 15 |
normal(前台) | 1 | 7 | 8 | 9 | 10 | 11 | 15 |
high | 1 | 11 | 12 | 13 | 14 | 15 | 15 |
realtime | 16 | 22 | 23 | 24 | 25 | 26 | 31 |
表 2 Win32 线程优先级 |