概述
线程优先级
Windows 系统有 32 种优先级,分别是 0(最低)到 31(最高)。Windows 是一种抢先式操作系统,意味着高优先级的线程会抢先低优先级的线程的执行,只要有高优先级的线程正在执行,低优先级的线程就不会有机会被调度。
Windows 系统并不直接对线程设置优先级,而是使用进程优先级类和线程相对优先级来设置一个线程的优先级。有多各种方法设置优先级类,可以使用 CreateProcess 创建子进程时传递给 fdwCreate 一个表示优先级类的标识符进行设置,还可以通过
BOOL SetPriorityClass(
HANDLE hProcess,
DWORD fdwPriority);
设置指定进程的优先级类,第三种方式是使用 start 命令行并指定的一个表示优先级选项来启动一个进程,还可以在任务管理器中设置一个进程的优先级。有 6 种进程优先级类,分别是
优先级类 | 标识符 |
实时 | REALTIME_PRIORITY_CLASS |
高 | HIGH_PRIORITY_CLASS |
高于默认 | ABOVE_NORMAL_PRIORITY_CLASS |
默认 | NROMAL_PRIORITY_CLASS |
低于默认 | BELOW_NORMAL_PRIORITY_CLASS |
空闲 | IDLE_PRIORITY_CLASS |
不能在 CreateThread 时设置新线程的相对优先级,只能通过
BOOL SetThreadPriority(
HANDLE hThread,
int nPriority);
设置一个指定线程的优先级,有 7 个相对优先级,分别是
相对优先级 | 常量标识符 |
时间关键 | THREAD_PRIORITY_TIME_CRITICAL |
最高 | THREAD_PRIORITY_HIGHEST |
高于默认 | THREAD_PRIORITY_ABOVE_NORMAL |
默认 | THREAD_PRIORITY_NORMAL |
低于默认 | THREAD_PRIORITY_BELOW_NORMAL |
最低 | THREAD_PRIORITY_LOWEST |
空闲 | THREAD_PRIORITY_IDLE |
线程优先级的动态提升
通常系统在处理一些 I/O 事件或磁盘读取时会动态提升相应线程的优先级,例如,用户按下一个按键,系统会将一个 WM_KEYDOWN 消息放入线程的消息队列中,键盘驱动程序会告诉系统临时提升线程的优先级来处理这个消息,默认情况提升 2 个级别,在第二个时间片,它的优先级降低 1,第三个时间片降到平常水平。系统仅对 1 到 15 之间的优先级做这种提升,这之间的优先级叫做动态优先级范围,系统不会对高于 15 级以上的线程做动态提升,另外,这个提升是由驱动程序告诉系统的。可以使用
BOOL SetProcessPriorityBoost(
HANDLE hProcess,
BOOL bDisablePriorityBoost);
BOOL SetThreadPriorityBoost(
HANDLE hThread,
BOOL bDisablePriorityBoost);
分别设置是否将相应进程或相应线程进行动态提升,使用
BOOL GetProcessPriorityBoost(
HANDLE hProcess,
PBOOL pbDisablePriorityBoost);
BOOL GetThreadPriorityBoost(
HANDLE hThread,
PBOOL pbDisablePriorityBoost);
来获得相应进程或线程是否禁用了动态提升。
另外,如果一个低优先级的线程已准备好执行,可是因为高优先级的线程正在一直执行,这种情况如果持续一段时间,一般是 3 到 4 秒钟,系统会临时将低优先级的线程的优先级提高到 15,并运行两个时间片的时间,然后再将的优先级降到平常水平,这样能保证低优先级的线程能得到执行。
I/O 请求优先级调度
当一个线程正在进行长时间的 I/O 请求时,系统因为慢速的 I/O 操作导致响应不畅,解决这个问题的办法是在开始 I/O 操作之前传递 THREAD_MODE_BACKGROUND_BEGIN 标志给 SetThreadPriority,告诉系统降低当前线程的优先级,在 I/O 完成之后传递 THREAD_MODE_BACKGROUND_END 标志给 SetThreadPriority 将优先级恢复到之前的状态;还可以使用 SetProcessClass 分别传递 PROCESS_MODE_BACKGROUND_BEGIN 和 PROCESS_MODE_BACKGROUND_END 来降低或恢复当前进程中所有线程的优先级,注意,只能对当前进程或线程进行这样的操作,不允许这样改变其它进程和其它线程的优先级。
最后
以上就是大力发夹为你收集整理的系统在处理一些 I/O 事件或磁盘读取时会动态提升相应线程的优先级的全部内容,希望文章能够帮你解决系统在处理一些 I/O 事件或磁盘读取时会动态提升相应线程的优先级所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复