如果你曾经用过windows的任务管理器,就算是没有学习过windows的内核你也应该有听说过“进程优先级“这么一个概念。虽然你可能没有操作过,但是你很有可能在任务管理器里面见过它。今天稍微讲一下Windows的进程优先级以及线程优先级。
Windows是一个抢断式多线程操作系统,在并发的处理的时候最基本的执行单结构是线程,而一个进程内并不是一个执行上不可分割的结构,而是由多个线程组成的。每一个线程在内核中有一个优先级顺序,这个顺序的取值范围是0-31,数字越大优先级越高。如果有任意一个高顺序的线程需要执行,Windows绝对不会执行低优先级的线程。如果低优先级的线程一直不能被执行,那么线程就被饥饿了,这个时候抢占式操作系统的特点就体现出来了。
但是为什么平时都没有注意到呢,这里很大的原因是平时绝大多数工作线程的的优先级都是基本差不多一致的,每一个线程基本都能分配到时间片。但是有的时候我们需要创建一些较高优先级或者较低优先级的线程用来完成一些特殊的任务,我们就要了解一下这个线程的优先顺序到底是如何计算出来的。
虽然说这个优先顺序的取值范围是0-31,但是你并不能直接通过API来设定优先顺序。你能够设定一个进程优先级以及一个线程优先级。下面是一个Windows的优先级对应表:
线程相对 优先级 | 进程优先级类 | |||||
---|---|---|---|---|---|---|
Idle | Below Normal | Normal | Above Normal | High | Real-Time | |
Time-critical | 15 | 15 | 15 | 15 | 15 | 31 |
Highest | 6 | 8 | 10 | 12 | 15 | 26 |
Above normal | 5 | 7 | 9 | 11 | 14 | 25 |
Normal | 4 | 6 | 8 | 10 | 13 | 24 |
Below normal | 3 | 5 | 7 | 9 | 12 | 23 |
Lowest | 2 | 4 | 6 | 8 | 11 | 22 |
Idle | 1 | 1 | 1 | 1 | 1 | 16 |
从这个表你可以看出来,实时优先级的进程拥有者极高的数值,通常情况下你不应该把你的进程优先级设置为实时。包括磁盘IO、鼠标显示、音频输出之类的系统功能都在实时优先级中的某些优先级中工作。如果你的线程优先级高于它们,并且需要大量CPU运算很有可能导致整个操作系统无法响应。不过微软在windows vista开始引入UAC之后开始限制了管理员账户的一些权限,现在你必须需要完全的UAC管理员权限才能把进程的优先级设置为实时,否则系统不会报错,但是最高会给你设置到高。
设置优先级的方法也非常简单,一种方法是创建进程或者创建线程的时候进行设置,另一种方法是通过专门的设置优先级的API进行设置。这里只介绍第二种通过专门的API设置的方法。
下面我给一种设置进程优先级的代码
//提升自身优先级到实时 HANDLE hProcess = OpenProcess(PROCESS_SET_INFORMATION, FALSE, GetCurrentProcessId()); if (SetPriorityClass(hProcess, REALTIME_PRIORITY_CLASS) == 0) { MessageBeep(0); MessageBox(0, L"设置进程优先级错误,推荐手动通过进程管理器设置优先级为实时", L"警告", 0); } CloseHandle(hProcess);
类似的你也可以通过
- SetProcessPriorityBoost
- SetThreadPriorityBoost
- SetThreadPriority
- SetPrioriytClass
等这一簇函数来完成。更详细资料请参考MSDN
从来都没整过这东东