有一些程序能够限制Windows中进程的CPU使用率。 例如BES和ThreadMaster 。 我需要编写自己的程序来完成与这些程序相同的function,但具有不同的configurationfunction。 有谁知道一个进程的CPU节stream是如何完成的(代码)? 我不是在谈论设置进程的优先级,而是如何将CPU使用率限制在例如15%,即使没有其他进程争夺CPU时间。
更新:我需要能够扼杀已经运行的任何进程,并且我没有源代码访问权限。
非常简化,它可以像这样工作:
GetProcessTimes
获取每个相关进程的“最后”值。 GetProcessAffinityMask
返回0,则调用SetProcessAffinityMask(old_value)
。 这意味着我们在上一次迭代中暂停了这个过程,现在让它有机会再次运行。 GetProcessTimes
来获取“当前”值 GetSystemTimeAsFileTime
cpu_usage = (deltacoreelTime + deltaUserTime) / (deltaTime)
old_value = GetProcessAffinityMask
其次是SetProcessAffinityMask(0)
,这将使进程脱机。 这基本上是在内核中运行的调度程序的一个非常原始的版本,在用户空间中实现。 如果使用的CPU时间超过了你认为正确的时间,那么它会让一个进程“休眠”一小段时间。 一个更复杂的测量可能会超过一秒或5秒是可能的(可能是可取的)。
您可能会试图暂停进程中的所有线程。 但是,重要的是不要摆脱优先级, 不要使用SuspendThread
除非你确切地知道程序在做什么,因为这很容易导致死锁和其他令人讨厌的副作用。 想想举个例子,当另一个线程仍在运行时试图获取同一个对象,暂停一个保留临界区的线程。 或者想象一下,在暂停十几个线程的过程中,你的进程会被换掉,其中一半运行,另一半运行。
另一方面,将亲和性掩码设置为零意味着从现在起,进程中没有任何单个线程在任何处理器上获得更多的时间片。 重置亲和力在同一时间给出原子性 – 所有线程都有可能再次运行。
不幸的是,至少根据文档, SetProcessAffinityMask
并不像SetThreadAffinityMask
那样返回旧的掩码。 因此,额外的Get...
调用是必要的。
您可能想要在作业对象中运行进程,并使用SetInformationJobObject
设置作业对象的最大CPU使用率(使用JOBOBJECT_CPU_RATE_CONTROL_INFORMATION
。
使用QueryProcessCycleTime来估计CPU的使用相当简单。 机器的处理器速度可以从HKLM \ HARDWARE \ DESCRIPTION \ System \ CentralProcessor \\〜MHz(其中是处理器编号,每个处理器存在一个条目)获得。 使用这些值,您可以使用Sleep()来估计进程的CPU使用情况,并根据需要生成CPU,以保持使用范围。