我想从 C 程序中读取 CPU 利用率统计数据,我对 CPU 使用百分比感兴趣,偷时间等等。这些统计信息显示在top
命令的第三行中。
我尝试用( ) 解析top
的输出,但在开始显示正确的统计数据之前,它似乎总是给出相同的“虚构”值。awk
top -n 1 -b | awk '{print $0}'
top
有没有办法从代码中或通过解析某些命令的输出来获取 CPU 利用率统计信息?
编辑:
平台是Linux
谢谢。
答案1
您想阅读 的前几行/proc/stat
。您需要读两遍,间隔一段测量的时间,然后用第二组数字减去第一组数字。这些行看起来像这样:
cpu 1526724 408013 600675 541100340 2861417 528 14531 0 0 0
cpu0 344507 77818 251244 134816146 1119991 324 13283 0 0 0
cpu1 502614 324065 179301 133991407 1631824 136 906 0 0 0
cpu2 299080 3527 79456 136144067 103208 59 255 0 0 0
cpu3 380521 2602 90672 136148719 6393 7 86 0 0 0
intr 2111239193 344878476 16943 ...
第一行是所有核心的聚合。接下来的几行显示了每个核心。当您看到以 开头的行时intr
,您就知道停止解析。
每个数字都是 CPU 在特定状态下花费的时间量。单位通常为百分之一秒。这些字段是user
, nice
, system
, idle
, iowait
, irq
, softirq
, steal
, guest
, 和guest_nice
。
权威文档当然是源代码。如果您手头有 Linux 内核源代码的副本,请查看fs/proc/stat.c
,特别是show_stat
函数。
答案2
有一些例子在网络上展示了如何用/proc/pid/stat
C 语言进行阅读。
您可以在两个不同时刻读取utime
或stime
值并计算所需的 CPU 利用率统计数据。 (我想top
也使用这个原始数据。)
(我忘了:这是 Linux 特有的。)
答案3
我已经使用以下 sysinfo 完成了此操作,这是片段
#include "sysinfo.h"
getstat(cpu_use,cpu_nic, cpu_sys, cpu_idl, cpu_iow, cpu_xxx, cpu_yyy, cpu_zzz, pgpgin, pgpgout, pswpin, pswpout, intr, ctxt, &running,&blocked, &dummy_1, &dummy_2);
float cpuconsumption = (float) (( (float) ((*cpu_use) + (*cpu_sys)) / (float)((*cpu_use)+(*cpu_sys)+(*cpu_idl)))*100);
答案4
如果有人想要直接从 ac 应用程序内部的顶部获取一些快速的 cpu 使用率值,此代码片段只是打开一个管道,并返回顶部进程的最后一行以及 cpu 信息。
/**
* Get last cpu load as a string (not threadsafe)
*/
static char* getCpuLoadString()
{
/*
* Easiest seems to be just to read out a line from top, rather than trying to calc it ourselves through /proc stuff
*/
static bool started = false;
static char buffer[1024];
static char lastfullline[256];
static int bufdx;
static FILE *fp;
if(!started) {
/* Start the top command */
/* Open the command for reading. */
fp = popen("top -b -d1", "r");
if (fp == NULL) {
printf("Failed to run top command for profiling\n" );
exit(1);
}
/* Make nonblocking */
int flags;
flags = fcntl(fileno(fp), F_GETFL, 0);
flags |= O_NONBLOCK;
fcntl(fileno(fp), F_SETFL, flags);
started = true;
}
/*
* Read out the latest info, and remember the last full line
*/
while( fgets (buffer + bufdx, sizeof(buffer) - bufdx, fp)!=NULL ) {
/* New data came in. Iteratively shift everything until a newline into the last full line */
char *newlinep;
while((newlinep = strstr(buffer, "\n"))) {
int shiftsize = (newlinep - buffer + 1);
*newlinep = 0; /* Nullterminate it for strcpy and strstr */
/* Check if the line contained "cpu" */
if(strstr(buffer, "Cpu")) {
strncpy(lastfullline, buffer, sizeof(lastfullline) - 1); /* Copy full line if it contained cpu info */
}
memmove(buffer, buffer + shiftsize, shiftsize); /* Shift left (and discard) the line we just consumed */
}
}
/*
* Return the last line we processed as valid output
*/
return lastfullline;
}
printf(" %s\n", getCpuLoadString());
然后我每秒都打电话