有些程序可以限制Windows中进程的CPU使用率。例如BES和ThreadMaster。我需要编写自己的程序,它与这些程序具有相同的功能,但具有不同的配置功能。有人知道如何完成CPU限制进程(代码)吗?我不是在谈论设置进程的优先级,而是如何将其CPU使用率限制为例如15%,即使没有其他进程在争用CPU时间。
更新:我需要能够限制已经运行的任何进程以及我没有源代码访问权限。
答案 0 :(得分:7)
您可能希望在作业对象中运行该进程,并使用SetInformationJobObject
设置JOBOBJECT_CPU_RATE_CONTROL_INFORMATION
作业对象的最大CPU使用率。
答案 1 :(得分:4)
非常简化,它可以以某种方式工作:
GetProcessTimes
一次,每个相关流程的价值。GetProcessAffinityMask
返回0,请致电SetProcessAffinityMask(old_value)
。这意味着我们在上一次迭代中暂停了该过程,现在我们再次给它机会再次运行。 GetProcessTimes
以获取"当前"值GetSystemTimeAsFileTime
cpu_usage = (deltaKernelTime + deltaUserTime) / (deltaTime)
old_value = GetProcessAffinityMask
,然后调用SetProcessAffinityMask(0)
,这会使进程脱机。这基本上是在内核中运行的调度程序的一个非常原始的版本,在userland中实现。它使一个过程"睡觉"如果它使用的CPU时间比你想象的要多,那么会花费很少的时间。一个更复杂的测量可能会超过一秒钟或5秒钟(并且可能是可取的)。
您可能想要暂停该进程中的所有线程。但是,除非您确切知道程序正在做什么,否则使用SuspendThread
来强调优先级和不非常重要,因为这很容易导致死锁和其他讨厌的副作用。例如,在另一个线程仍在运行并尝试获取同一对象时,暂停一个持有临界区的线程。或者想象一下,在暂停十几个线程的过程中,你的进程被换掉了,剩下一半在运行,另一半则死了。
另一方面,将关联掩码设置为零只意味着从现在开始,进程中没有任何单个线程在任何处理器上获得更多时间片。重置亲和力同时给出了原子,所有线程都可以再次运行。
不幸的是,SetProcessAffinityMask
不会像SetThreadAffinityMask
那样返回旧掩码,至少根据文档。因此,需要额外的Get...
电话。
答案 2 :(得分:0)
使用QueryProcessCycleTime估算CPU的使用情况非常简单。机器的处理器速度可以从HKLM \ HARDWARE \ DESCRIPTION \ System \ CentralProcessor \\ ~MHz获得(其中是处理器编号,每个处理器存在一个条目)。使用这些值,您可以使用Sleep()估计进程的CPU使用率并根据需要生成CPU,以保持您的使用范围。