10

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

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

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

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

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

4

4 回答 4

10

/proc/PID/stat您可以在 PID 是您的父进程的进程 ID 的位置找到此信息。假设父进程等待其子进程,则可以从utimestimecutimecstime计算总 CPU 使用率:

运行时间 %lu

此进程已在用户模式下调度的时间量,以时钟滴答数衡量(除以 sysconf(_SC_CLK_TCK)。这包括来宾时间、来宾时间(运行虚拟 CPU 所花费的时间,见下文),以便不知道的应用程序的客人时间字段不会从他们的计算中丢失那个时间。

时间%lu

此进程已在内核模式下调度的时间量,以时钟滴答数衡量(除以 sysconf(_SC_CLK_TCK)。

可爱的 %ld

此进程的等待子进程已在用户模式下调度的时间量,以时钟滴答数衡量(除以 sysconf(_SC_CLK_TCK)。(另请参见 times(2)。)这包括来宾时间、cguest_time(运行虚拟机所花费的时间) CPU,见下文)。

cstime %ld

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

有关详细信息,请参见proc(5) 联机帮助页

于 2012-10-13T08:27:08.887 回答
3

当然,您可以使用良好的旧 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

享受!

于 2012-10-14T13:58:45.820 回答
2

可能不是确切的命令。但是您可以执行以下操作来获取各种进程的 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

于 2012-10-13T08:39:12.333 回答
1

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

top -b -d 5 -n 2 | awk '$1 == "PID" {block_num++; next} block_num == 2 {sum += $9;} END {print sum}'
于 2015-07-23T11:06:22.447 回答