【问题标题】:How to calculate CPU utilization of a process & all its child processes in Linux?如何计算Linux中一个进程及其所有子进程的CPU利用率?
【发布时间】:2012-10-03 23:29:27
【问题描述】:

我想知道 Linux 中某个进程和所有子进程在固定时间段内的 CPU 利用率。

更具体地说,这是我的用例:

有一个等待用户请求执行程序的进程。为了执行程序,该进程调用子进程(一次最多 5 个),并且每个子进程执行其中 1 个提交的程序(假设用户一次提交 15 个程序)。因此,如果用户提交 15 个程序,则将运行 3 批,每批 5 个子进程。子进程在完成程序执行后立即被杀死。

我想知道这 15 个程序执行期间父进程及其所有子进程的 CPU 利用率百分比。

有没有使用 top 或其他命令的简单方法来做到这一点? (或者我应该附加到父进程的任何工具。)

【问题讨论】:

    标签: linux cpu-usage


    【解决方案1】:

    您可以在/proc/PID/stat 中找到此信息,其中 PID 是您的父进程的进程 ID。假设父进程等待其子进程,则可以根据 utimestimecutimecstime:

    utime %lu

    此进程在用户模式下安排的时间量, 以时钟节拍测量(除以 sysconf(_SC_CLK_TCK)。这包括 来宾时间,来宾时间(运行虚拟 CPU 所花费的时间,见下文), 这样不知道来宾时间字段的应用程序就不会 从他们的计算中浪费时间。

    时间 %lu

    这个进程在内核模式下被调度的时间, 以时钟节拍测量(除以 sysconf(_SC_CLK_TCK)。

    cutime %ld

    这个进程等待子进程的时间 在用户模式下调度,以时钟节拍测量(除以 系统配置(_SC_CLK_TCK)。 (另见次(2)。)这包括客人时间, cguest_time(运行虚拟 CPU 所花费的时间,见下文)。

    cstime %ld

    这个进程等待子进程的时间 在内核模式下调度,以时钟滴答测量(除以 sysconf(_SC_CLK_TCK)。

    详情请见proc(5) manpage

    【讨论】:

    • 父进程等待子进程是什么意思?如果子进程被派生在后台运行,这种技术会失败吗?
    【解决方案2】:

    当然,您也可以使用良好的旧 C 以硬核方式完成它

    find_cpu.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    
    #define MAX_CHILDREN 100
    
    /**
     *  System command execution output
     *    @param <char> command - system command to execute
     *    @returb <char> execution output
     */
    char *system_output (const char *command)
    {
      FILE *pipe;
      static char out[1000];
      pipe = popen (command, "r");
      fgets (out, sizeof(out), pipe);
      pclose (pipe);
      return out;
    }
    
    /**
     *  Finding all process's children
     *    @param <Int> - process ID 
     *    @param <Int> - array of childs
     */
    void find_children (int pid, int children[])
    {
      char empty_command[] = "/bin/ps h -o pid --ppid ";
      char pid_string[5];
    
      snprintf(pid_string, 5, "%d", pid);
    
      char *command = (char*) malloc(strlen(empty_command) + strlen(pid_string) + 1);
      sprintf(command, "%s%s", empty_command, pid_string);
    
      FILE *fp = popen(command, "r");
    
      int child_pid, i = 1;
      while (fscanf(fp, "%i", &child_pid) != EOF)
      {
        children[i] = child_pid;
        i++;
      }
    }
    
    /**
     *  Parsign `ps` command output
     *    @param <char> out - ps command output
     *    @return <int> cpu utilization
     */
    float parse_cpu_utilization (const char *out)
    {
      float cpu;
      sscanf (out, "%f", &cpu);
      return cpu;
    }
    
    
    int main(void)
    {
      unsigned pid = 1;
    
      // getting array with process children
      int process_children[MAX_CHILDREN] = { 0 };
      process_children[0] = pid; // parent PID as first element
      find_children(pid, process_children);
    
      // calculating summary processor utilization
      unsigned i;
      float common_cpu_usage = 0.0;
      for (i = 0; i < sizeof(process_children)/sizeof(int); ++i) 
      {
        if (process_children[i] > 0) 
        {
          char *command = (char*)malloc(1000);
          sprintf (command, "/bin/ps -p %i -o 'pcpu' --no-headers", process_children[i]);
          common_cpu_usage += parse_cpu_utilization(system_output(command));
        }
      }
      printf("%f\n", common_cpu_usage);
      return 0;
    }
    

    编译:

    gcc -Wall -pedantic --std=gnu99 find_cpu.c
    

    享受吧!

    【讨论】:

    • 调用 popen 来调用外部实用程序来完成工作并不是真正的“硬核”使用 C 的方式。;)
    【解决方案3】:

    可能不是确切的命令。但是您可以执行以下操作来获取各种进程的 cpu 使用情况并添加它。

    #ps -C sendmail,firefox -o pcpu= | awk '{s+=$1} END {print s}'

    /proc/[pid]/stat 进程的状态信息。这被 ps 使用并制成人类可读的形式。

    另一种方法是使用 cgroups 并使用 cpuacct。

    http://www.kernel.org/doc/Documentation/cgroups/cpuacct.txt

    https://access.redhat.com/knowledge/docs/en-US/Red_Hat_Enterprise_Linux/6/html/Resource_Management_Guide/sec-cpuacct.html

    【讨论】:

      【解决方案4】:

      这是计算所有进程的总 CPU 的单行程序。您可以通过将列过滤器传递到顶部输出来调整它:

      top -b -d 5 -n 2 | awk '$1 == "PID" {block_num++; next} block_num == 2 {sum += $9;} END {print sum}'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多