我需要编写一个消耗固定部分处理器的程序,我正在考虑更改优先级,但这种方法不会将CPU使用限制在固定的百分比,例如60%。 谢谢!
答案 0 :(得分:2)
取决于您希望此限制的时间段 - 如果您希望绝对限制从不使用超过60%(或更少),那么它就无法可靠完成您的要求(不使用任何其他外部命令或程序) - 在一天结束时,操作系统决定你得到多少时间。
但是,如果您只想平均 ,那么您可能会这样做(有一些限制)。 基本上,设置一个循环,记录系统启动时的时间,执行少量工作,然后记下新的系统时间。现在睡眠过程为2 / 3rds(60%)的差异。你需要保持缓冲,因为不能确保你不会长时间睡觉。 另外,如果你正在运行一个可预先占用的内核(现在大多数都是这样),那么你就会遇到麻烦,因为循环执行本身可以被接管。
tl;博士:你可以在没有外部代码的情况下大致做到这一点,但它只是大致正确。
答案 1 :(得分:1)
这是一个讨论获取CPU统计信息的几种方法的线程:http://www.cyberciti.biz/tips/how-do-i-find-out-linux-cpu-utilization.html。至少,您可以通过读取/ sys / devices / xxx / cpuN以编程方式获得CPU利用率。
有办法做你想做的事,但你没有给我们足够的细节你的目标。如果您想影响能耗,您可以简单地最大化一个处理器(减去其他应用程序的负载)。如果要影响一个应用程序的执行,则需要更加聪明。如果您想在处理器上放置一般固定负载,无论您的应用程序套件如何,它都会变得非常复杂,我们需要了解您的用例。
除此之外,还有其他一些你应该注意的事情。首先,您需要确定您希望利用率的粒度。这就是我的意思。通过窗口评估CPU利用率。例如,平均利用率可能为60%,但如果您的利用率计算窗口为2秒,则可能计算为.6 * 2或1.2秒,闲置为.8秒。而.8sec是现代处理器上的长时间。在弄清楚你想要什么颗粒之后,你可以使用奥利弗建议的技术。另一种技术是测量当前的CPU利用率,然后计算睡眠与工作所需的毫秒数之比。然后执行一个简单的循环并调用您最喜欢的睡眠功能。 (关于计算循环的警告。现代编译器在优化方面很擅长并且可能会缩短计算循环所需的时间长度。)您还需要确保此利用率分布在所有处理器上。我不打算因超线程而出现并发症。
当您确定粒度时,请注意,无论API允许什么,大多数Linux系统(或任何其他系统)的时序分辨率都不超过10毫秒。
Re:最大化一个CPU的负载。我怀疑这对你有用。如果您的应用程序是单线程的,那么将负载放在另一个CPU上不会影响应用程序的性能。如果您的应用程序线程非常严格,它可能仍然无法工作,因为某些操作系统会尝试均衡CPU上的负载,这意味着它可能仍会使您的线程远离负载较重的CPU,并再次不会影响您的应用程序以你想要的方式。
总之,我们必须了解更多,才有机会提供解决方案。
PS I您对Oliver的评论中使用的代码不起作用,因为您没有进行任何处理。
答案 2 :(得分:0)
我猜https://github.com/opsengine/cpulimit
可以为你完成这项工作。它是开源的,所以也请查看源代码并将其分叉ftw!
答案 3 :(得分:0)
运行一个消耗几乎恒定的CPU值(CPU时间)的程序必须要解决许多挑战。即使您使用cpulimit
,也必须考虑至少三个要素:
cpulimit
时,您可以设置上限。您的流程可能会少用。为了始终设置几乎恒定的值,您可能不仅需要限制进程的CPU,还要限制所有其他CPU的CPU。top
和其他工具报告的CPU百分比对应于每个核心(或超线程CPU的线程)上使用的百分比。如果使用cpulimit
等使用工具限制进程使用50%,则将进程限制为核心的50%。如果您有8个内核,则必须使用400%的值将CPU消耗限制为一半内核。使用cpulimit
cpulimit
设置一个或多个进程的CPU消耗的上限。它监视进程并向进程发送信号,以便在它开始消耗超过限制时暂停执行。当CPU消耗低于限制时,它将恢复该过程。
考虑您运行一个受CPU限制的进程,例如md5sum /dev/zero &
,您可以使用top
来验证进程是否使用100%的CPU并使用cpulimit
来限制CPU消耗。请注意,该命令返回进程的进程ID(pid)。示例中的77
$ md5sum /dev/zero &
[1] 77
要限制CPU消耗,您可以使用cpulimit
和系统报告的进程ID。以下是一个例子。您可以使用-v
来获取详细消息。请注意,即使您将25%设置为限制,CPU消耗总是不是25%,有时会低于(21.30%),有时会进一步降低(36.87%)
$ sudo cpulimit --verbose --limit=25 --pid=77
4 CPUs detected.
Priority changed to -10
Process 77 detected
%CPU work quantum sleep quantum active rate
26.99% 46144 us 53855 us 49.83%
21.30% 65714 us 34285 us 55.98%
28.47% 47762 us 52237 us 54.39%
36.45% 39202 us 60797 us 57.16%
36.87% 37513 us 62486 us 55.33%
:
进程id(pid)也可用于向进程发送信号。例如,您可以使用kill
发送SIGSTOP
信号并暂停其执行。您可以发送SIGCONT
信号以恢复执行。
$ kill -s SIGSTOP 77 # suspend the execution of process 77 (it will use 0% CPU)
$ kill -s SIGCONT 77 # resume the execution of process 77
cpulimit如何运作
您可以在Github中获取cpulimit
的源代码。
$ git clone https://github.com/opsengine/cpulimit.git
$ cd cpulimit
$ make # compile the code
$ sudo cp src/cpulimit /usr/bin # install the command
基本上,cpulimit
创建一个进程组,其中包含它控制的所有进程。您可以查看process_group.c
文件。它包括创建和更新该linux进程组的函数。此外,还有其他功能可以通过pid或名称查找进程并将其添加到组中。 update_process_group
函数用于不断更新组中进程的CPU消耗。
在cpulimit.c
中,limit_process
执行所有工作。有一个while(1) { ... }
无限循环,用于检查每个进程消耗的CPU。如果进程消耗超过限制,它将发送SIGSTOP(挂起)信号。如果进程暂停并使用少于限制,则发送SIGCONT(resume)信号。
一个想法:如何实施您的计划
我已经看过" cpulimit"的源代码。但是我没有找到如何使我的c程序完全浪费,例如60%的处理器!
要创建始终使用50%CPU的进程,必须监视在同一核心中运行的其他进程,并限制所有这些进程所消耗的时间。同一核心中其他进程使用的CPU总和不得超过50%。您可以定义CPU关联,以设置哪些进程将始终在同一个核心上运行。
$ taskset -p -c 0 77 # make that process 77 use the core 0
您可能会发现一些shell scripts采用符合某些条件的所有正在运行的进程,并使用cpulimit
限制其CPU消耗。以下是限制使用超过20%CPU的所有进程的示例。
#!/bin/bash
while sleep 3 # execute each 3 seconds
do
# get the processes that use more than 20% of CPU
PIDS=`top -b -n1 | tail -n +8 | gawk '$9>20 {print $1}'`
for i in $PIDS
do
# limit the new violating processes to 20%
cpulimit -p $i -l 20 -z &
done
done
另一个想法:使用cgroups(?)
作为cpulimit
的替代方案,您可以探索使用Process Control Groups (cgroups)。这些组与cpulimit
使用的进程组不同。 cgroup是Linux内核的一项功能,允许您为进程组设置限制。例如,它可用于限制管理进程使用的CPU和网络,并减少这些任务对在同一台机器上运行的服务器的干扰。