SetThreadPriority 和 SetPriorityClass

use*_*591 8 windows multithreading

我不明白如何使用SetThreadPriority以及SetPriorityClass降低和提高线程的优先级。

我的理解是,SetPriorityClass选择进程可用的优先级范围,并SetThreadPriority设置类内的相对优先级。

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

SetPriorityClass(GetCurrentProcess(), PROCESS_MODE_BACKGROUND_BEGIN);

SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_END);
Run Code Online (Sandbox Code Playgroud)

感谢帮助。

Rol*_*kas 11

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即使该线程是进程中唯一的线程,也不会产生如此可怕的影响。 另请注意,您需要仅使用 来永久
关闭。之后打电话是不够的。 因此,Arno对于消除单个线程的影响的说法并不完全正确。PROCESS_MODE_BACKGROUND_BEGINPROCESS_MODE_BACKGROUND_ENDTHREAD_MODE_BACKGROUND_ENDPROCESS_MODE_BACKGROUND_BEGIN
THREAD_MODE_BACKGROUND_ENDPROCESS_MODE_BACKGROUND_BEGIN

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

  • 在 Windows 11 上报告了一些不良的 Chrome 安装程序行为后,我刚刚遇到了这个问题 (https://crbug.com/1475179)。然后,我在 Windows 10 上使用一个简单的测试程序重现了工作集上限。所以,是的。这(仍然没有记录的行为)有可能使你的代码运行速度慢 100 倍。疯狂。 (4认同)

Arn*_*rno 3

进程优先级和线程优先级共同构建了base priority线程。请参阅安排优先级以了解如何组合优先级。通过查看此列表,您可以清楚地看出您的理解在某种程度上是正确的;在某个优先级类别内,base priority可以有不同的值,由 确定thread priority

并非所有 Windows 版本都支持 的值和PROCESS_MODE_BACKGROUND_BEGIN的值。SetPriorityClassTHREAD_MODE_BACKGROUND_ENDSetThreadPriority

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

THREAD_MODE_BACKGROUND_END: 结束后台处理模式。系统将线程的资源调度优先级恢复为线程进入后台处理模式之前的状态。

这里讨论的场景的结果是可以预见的:会将SetPriorityClass进程及其所有线程设置为background processing mode. 以下SetThreadPriority只会释放来自 的线程background processing mode。但该进程的所有其他可能的线程将保持在后台处理模式。

注意:只有process priority class 的组合thread priority才能确定base priority. 因此,无论是调用GetThreadPriority还是调用都GetPriorityClass不会返回基本优先级。只有它们的组合才能释放上面“调度优先级”链接中描述的基本优先级。不幸的是,新background processing mode值尚未包含在base priority列表中。但名称base priority说明了这里的重要性:基于基本优先级(源自进程优先级类别和线程优先级),调度程序可以动态调整调度优先级。后台模式只是fine tune调度优先级的另一种方式。另一种方法是优先级提升。优先级提升功能已经存在了一段时间。新的访问background processing modeSetThreadPrioritySetPriorityClass直接打开优先级提升功能。在 Windows XP 中,这必须通过调用SetProcessPriorityBoost来完成。

  • 我检查了“GetProcessWorkingSetSizeEx”:进入后台模式后,最大工作集将限制为 32MB,并且还设置了“QUOTA_LIMITS_HARDWS_MAX_ENABLE”标志。如果我不进入后台模式,那么最大工作集参数甚至会是一个小得多的值:大约 1.35MB,即使在分配了巨大的内存之后也是如此。但由于设置了“QUOTA_LIMITS_HARDWS_MAX_DISABLE”标志,因此最大工作集不会对实际工作集产生任何影响。我不知道是否调用了“EmptyWorkingSet”,但据我了解,它无论如何都不会更改工作集参数? (3认同)