如何限制进程在Windows上的CPU使用率? (需要代码,而不是应用程序)

时间:2012-02-19 20:53:05

标签: windows winapi cpu-usage

有些程序可以限制Windows中进程的CPU使用率。例如BESThreadMaster。我需要编写自己的程序,它与这些程序具有相同的功能,但具有不同的配置功能。有人知道如何完成CPU限制进程(代码)吗?我不是在谈论设置进程的优先级,而是如何将其CPU使用率限制为例如15%,即使没有其他进程在争用CPU时间。

更新:我需要能够限制已经运行的任何进程以及我没有源代码访问权限。

3 个答案:

答案 0 :(得分:7)

您可能希望在作业对象中运行该进程,并使用SetInformationJobObject设置JOBOBJECT_CPU_RATE_CONTROL_INFORMATION作业对象的最大CPU使用率。

答案 1 :(得分:4)

非常简化,它可以以某种方式工作:

  1. 使用一些合理的小等待时间(可能是100毫秒)创建一个定期的等待计时器。得到一个"最后"通过调用GetProcessTimes一次,每个相关流程的价值。
  2. 永远循环,阻止计时器。
  3. 每次醒来时:
    • 如果 GetProcessAffinityMask返回0,请致电SetProcessAffinityMask(old_value)。这意味着我们在上一次迭代中暂停了该过程,现在我们再次给它机会再次运行。
    • 其他致电GetProcessTimes以获取"当前"值
    • 致电GetSystemTimeAsFileTime
    • 通过从当前
    • 中减去最后一个来计算delta
    • cpu_usage = (deltaKernelTime + deltaUserTime) / (deltaTime)
    • 如果这比您想要的更多,请拨打old_value = GetProcessAffinityMask,然后调用SetProcessAffinityMask(0),这会使进程脱机。
  4. 这基本上是在内核中运行的调度程序的一个非常原始的版本,在userland中实现。它使一个过程"睡觉"如果它使用的CPU时间比你想象的要多,那么会花费很少的时间。一个更复杂的测量可能会超过一秒钟或5秒钟(并且可能是可取的)。

    您可能想要暂停该进程中的所有线程。但是,除非您确切知道程序正在做什么,否则使用SuspendThread来强调优先级和非常重要,因为这很容易导致死锁和其他讨厌的副作用。例如,在另一个线程仍在运行并尝试获取同一对象时,暂停一个持有临界区的线程。或者想象一下,在暂停十几个线程的过程中,你的进程被换掉了,剩下一半在运行,另一半则死了。

    另一方面,将关联掩码设置为零只意味着从现在开始,进程中没有任何单个线程在任何处理器上获得更多时间片。重置亲和力同时给出了原子,所有线程都可以再次运行。

    不幸的是,SetProcessAffinityMask不会像SetThreadAffinityMask那样返回旧掩码,至少根据文档。因此,需要额外的Get...电话。

答案 2 :(得分:0)

使用QueryProcessCycleTime估算CPU的使用情况非常简单。机器的处理器速度可以从HKLM \ HARDWARE \ DESCRIPTION \ System \ CentralProcessor \\ ~MHz获得(其中是处理器编号,每个处理器存在一个条目)。使用这些值,您可以使用Sleep()估计进程的CPU使用率并根据需要生成CPU,以保持您的使用范围。