Top is the most common command to view CPU usage under Linux, which is powerful and easy to use. But one thing is very bad, is top's working state is full screen, and cannot return. It's hard to get CPU utilization if you want to call the top command in a C program.
So we need a simplified version of top.
The top command works by reading the stat file under the/proc folder to get CPU usage.
Stat The first few behaviors of the file CPU use information description. The exact number of rows depends on how many CPUs the system has, but the fields in the row are the same. The first line starts with the string ' CPU ', which is the total CPU usage for the system. The remaining lines begin with a ' CPU ' +cpuid to describe a single CPU separately.
The first line reads as follows:
CPU 15718 197 2574 136003 3881 690 531 0
The unit of the number is user_hz (1/100ths of a second on most architectures). The first string is the CPU identifier, followed by four digits in the user state consumption time slice, in the low priority user state consumption time slice, the kernel state consumption time slice as well as the idle time slice.
2.4 Kernel, the above is the entire contents of the CPU usage information. But in the 2.6 kernel, this line also has three additional data. The time slice that is consumed by operation such as IOWAIT,IRQ,SOFTIRQ respectively.
Refer to BusyBox's top source code and modify it as follows:
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <errno.h>
#define SMLBUFSIZ 256
typedef unsigned long long ul_t;
typedef struct CPU_T {
ul_t u, N, S, I, W, X, Y, Z; As represented In/proc/stat
ul_t U_sav, S_sav, N_sav, I_sav, W_sav, X_sav, Y_sav, Z_sav; In, our display
} cpu_t;
cpu_t *cpus_refresh (cpu_t *cpus)
{
static FILE *FP = NULL;
int i;
int num;
Char Buf[smlbufsiz];
if (!FP) {
if (!) ( fp = fopen ("/proc/stat", "R"))
fprintf (stderr, "Failed/proc/stat Open:%s", Strerror (errno));
}
Rewind (FP);
Fflush (FP);
The ' last slot with the ' CPU summary line
if (!fgets (buf, sizeof (BUF), FP)) fprintf (stderr, "Failed/proc/stat read");
cpus->x = 0;
cpus->y = 0;
cpus->z = 0;
num = sscanf (buf, CPU%Lu%Lu%Lu%Lu%Lu%Lu%Lu%Lu)
&cpus->u,
&cpus->n,
&cpus->s,
&cpus->i,
&cpus->w,
&cpus->x,
&cpus->y,
&cpus->z
);
if (num < 4)
fprintf (stderr, "Failed/proc/stat read");
return CPUs;
}
static void Format_output (cpu_t *cpu, const char *pfx)
{
#define TRIMZ (x) (TZ = (long Long) (x)) < 0 0:tz)
Long Long u_frme, S_frme, N_frme, I_frme, W_frme, X_frme, Y_frme, Z_frme, Tot_frme, TZ;
float scale;
U_frme = cpu->u-cpu->u_sav;
S_frme = cpu->s-cpu->s_sav;
N_frme = cpu->n-cpu->n_sav;
I_frme = Trimz (CPU->I-CPU->I_SAV);
W_frme = cpu->w-cpu->w_sav;
X_frme = cpu->x-cpu->x_sav;
Y_frme = cpu->y-cpu->y_sav;
Z_frme = cpu->z-cpu->z_sav;
Tot_frme = u_frme + s_frme + n_frme + i_frme + w_frme + x_frme + y_frme + z_frme;
if (Tot_frme < 1) tot_frme = 1;
Scale = 100.0/(float) tot_frme;
fprintf (stderr, "%s:%.2f%%us,%.2f%%sy,%.2f%%ni,%.2f%%id,%.2f%%wa,%.2f%%hi,%.2f%%si,%.2f%%st/n",
pFX
(float) u_frme * scale,
(float) s_frme * scale,
(float) n_frme * scale,
(float) i_frme * scale,
(float) w_frme * scale,
(float) x_frme * scale,
(float) y_frme * scale,
(float) z_frme * scale);
Cpu->u_sav = cpu->u;
Cpu->s_sav = cpu->s;
Cpu->n_sav = cpu->n;
Cpu->i_sav = cpu->i;
Cpu->w_sav = cpu->w;
Cpu->x_sav = cpu->x;
Cpu->y_sav = cpu->y;
Cpu->z_sav = cpu->z;
#undef TRIMZ
}
int main () {
cpu_t * CPU;
CPU = (cpu_t *) malloc (sizeof (cpu_t));
memset (cpu,0,sizeof (cpu_t));
while (1) {
Cpus_refresh (CPU);
Format_output (CPU, "CPU usage:");
Sleep (1);
}
}
It should be noted that no matter what method, we can not get to the system instantaneous CPU utilization, but only through the recent use of the situation to speculate.
In this program, the first call to Cpus_refresh is not the current CPU usage, but the CPU usage so far since the system started, which does not reflect current CPU usage. The second call to calculate the difference is the CPU usage in this second, and it is reasonable to use it to measure the current instantaneous usage rate.