SetThreadPriority和SetPriorityClass

时间:2012-11-29 17:46:27

标签: windows multithreading

我不明白如何使用SetThreadPrioritySetPriorityClass来降低和提高线程的优先级。

我的理解是SetPriorityClass选择了流程可用的优先级范围,SetThreadPriority设置了班级中的相对优先级。

例如,为线程执行此操作的结果是什么:

SetPriorityClass(GetCurrentProcess(), PROCESS_MODE_BACKGROUND_BEGIN);

SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_END);

感谢您的帮助。

2 个答案:

答案 0 :(得分:3)

进程优先级和线程优先级正在构建线程的base priority。请参阅Scheduling Priorities以了解优先级的组合方式。通过查看此列表,您的理解显然有些正确;在某个优先级内,base priority可以有各种值,由thread priority确定。

所有Windows版本均不支持PROCESS_MODE_BACKGROUND_BEGIN的{​​{1}}值和SetPriorityClass的{​​{1}}值。

<强> PROCESS_MODE_BACKGROUND_BEGIN: 系统降低了进程(及其线程)的资源调度优先级,以便它可以执行后台工作,而不会显着影响前台的活动。

<强> THREAD_MODE_BACKGROUND_END: 结束后台处理模式。系统恢复线程的资源调度优先级,就像线程进入后台处理模式之前一样。

这里讨论的场景的结果是可预测的:THREAD_MODE_BACKGROUND_END将把所有线程的进程设置为SetThreadPriority。以下SetPriorityClass只会从background processing mode释放一个帖子。但是进程的所有其他可能线程将保持处于后台处理模式。

注意:只有SetThreadPriority background processing mode的组合才会确定process priority class。因此,对thread priority的调用和对base priority的调用都不会返回基本优先级。只有它们的组合才会释放上面“调度优先级”链接中描述的基本优先级。不幸的是,新的GetThreadPriority值尚未包含在GetPriorityClass列表中。但是名称background processing mode告诉了这里重要的事项:基于基本优先级(从进程优先级和线程优先级派生),允许调度程序动态调整调度优先级。后台模式只是base priority调度优先级的另一种方式。另一种方式是Priority Boosts。优先级提升功能已存在一段时间。对base priorityfine tune的{​​{1}}值的新访问权限可直接打开优先级提升功能。在Windows XP中,这必须通过调用SetProcessPriorityBoost来完成。

答案 1 :(得分:3)

我观察到PROCESS_MODE_BACKGROUND_BEGIN的一件事,但显然没有记录,至少在Windows 7下,永久清空过程的工作集,无论如何进程访问内存 - 直到后台模式结束。

例如,通常没有PROCESS_MODE_BACKGROUND_BEGIN,当我的机器具有千兆字节的可用内存,并且该进程需要消耗并不断处理千兆字节的内存时,进程工作集将是关于等于分配大小。也就是说,该进程获取它在其工作集中使用的所有内存。好。
现在,PROCESS_MODE_BACKGROUND_BEGIN 工作集将是几十兆字节!
不好的结果是,这会导致不断的页面错误,并且计算运行得慢得多!页面错误可能不是页面文件,而是Windows缓存内存。但页面错误仍然会显着降低计算速度,同时导致CPU被无意义的负载消耗。

总之,PROCESS_MODE_BACKGROUND_BEGIN不适合低优先级背景工作。这项工作将是非常时间和能源效率低下
PROCESS_MODE_BACKGROUND_BEGIN仅适用于流程确实无意在后台消费的任何内容

相比之下THREAD_MODE_BACKGROUND_BEGIN没有这样可怕的效果,即使线程是进程中唯一的线程。
另请注意,您需要仅使用PROCESS_MODE_BACKGROUND_BEGIN关闭PROCESS_MODE_BACKGROUND_END。仅在THREAD_MODE_BACKGROUND_END之后致电PROCESS_MODE_BACKGROUND_BEGIN是不够的。
因此,即使对于单个线程,THREAD_MODE_BACKGROUND_END撤消PROCESS_MODE_BACKGROUND_BEGIN的影响,Arno也不完全正确。

附加说明:SetProcessPriorityBoostbDisablePriorityBoost = TRUE对工作集没有任何此类影响。