我只是想知道是否有一种优雅的方法可以为执行密集计算的特定线程设置最大 CPU 负载。
现在我找到了线程中最耗时的循环(它只进行压缩)并使用GetTickCount()
硬Sleep()
编码值。它确保循环持续一段时间,然后休眠一段最短时间。它或多或少地完成了这项工作,即保证线程不会使用超过 50% 的 CPU。
但是,行为取决于 CPU 内核的数量(巨大的劣势)和丑陋的(较小的劣势:))。
有任何想法吗?
5 回答
我不知道有任何 API 可以让操作系统的调度程序执行您想要的操作(即使您的线程是空闲优先级的,如果没有更高优先级的就绪线程,您的线程也会运行)。但是,我认为您可以根据您已经在做的事情即兴创作一个相当优雅的节流功能。本质上(我手边没有 Windows 开发机器):
选择线程在每次迭代时休眠的默认时间量。然后,在每次迭代中(或在每第 n 次迭代中,这样节流函数本身不会成为显着的 CPU 负载),
- 计算自上次调用节流函数以来线程使用的 CPU 时间量(我将称之为 dCPU)。您可以使用GetThreadTimes() API 来获取线程已执行的时间量。
- 计算自上次调用节流函数以来经过的实时时间量(我将称之为 dClock)。
- dCPU / dClock 是 CPU 使用百分比(一个 CPU)。如果它高于你想要的,增加你的睡眠时间,如果低于,减少睡眠时间。
- 让您的线程休眠计算的时间。
根据您的看门狗如何计算 CPU 使用率,您可能需要使用GetProcessAffinityMask()来找出系统有多少 CPU。dCPU / (dClock * CPUs) 是可用总 CPU 时间的百分比。
您仍然需要为初始睡眠时间和递增/递减量选择一些神奇的数字,但我认为可以调整该算法以使线程以相当接近确定的 CPU 百分比运行。
在 linux 上,您可以使用 nice() 更改线程的调度优先级。
我想不出您想要的任何跨平台方式(或任何有保证的方式句号),但是当您使用 GetTickCount 时,您可能对跨平台不感兴趣:)
我会使用进程间通信并设置密集的进程很好的级别来获得你需要的东西,但我不确定这是否适合你的情况。
编辑:我同意伯纳德的观点,这就是为什么我认为一个过程而不是一个线程可能更合适,但它可能不适合你的目的。
问题是当你有工作要做时想让 CPU 空闲是不正常的。通常,您将后台任务设置为空闲优先级,并让操作系统处理调度它所有未被交互任务使用的 CPU 时间。
在我看来,问题在于看门狗进程。
如果您的后台任务受 CPU 限制,那么您希望它为任务占用所有未使用的 CPU 时间。
也许你应该看看修复看门狗程序?
您可能能够更改线程的优先级,但更改最大利用率将需要轮询和黑客来限制正在发生的事情的数量,或者使用可以设置进程最大利用率的操作系统工具。但是,我没有看到您想要这样做的任何情况。