限制C程序的CPU使用

时间:2014-04-25 12:25:59

标签: c linux cpu-usage

我需要编写一个消耗固定部分处理器的程序,我正在考虑更改优先级,但这种方法不会将CPU使用限制在固定的百分比,例如60%。 谢谢!

4 个答案:

答案 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,也必须考虑至少三个要素:

  • 必须限制哪些进程:当前的Linux CFS调度程序会尝试为需要CPU并具有相同优先级的所有进程提供相同的时间。然后,如果在具有单核的计算机中运行两个CPU限制进程,它将尝试为它们提供相同的CPU时间。使用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和网络,并减少这些任务对在同一台机器上运行的服务器的干扰。

您可以查看solution that limits the CPU usage using cgroup