Linux Cpu 利用率计算
轉載:http://blog.chinaunix.net/uid-20057401-id-1979033.html
前幾天要寫一個取得linux performance的函數。查詢了一些資料。發現有幾種計算cpu利用率的方法。但是都不怎么正確。最后查了以下top的源代碼。現列出其計算cpu利用率的關鍵函數
?
c代碼如下:
typedef struct CPU_t { ?
? ?TIC_t u, n, s, i, w, x, y, z; // as represented in /proc/stat ?
? ?TIC_t u_sav, s_sav, n_sav, i_sav, w_sav, x_sav, y_sav, z_sav; // in the order of our display ?
? ?unsigned id; ?// the CPU ID number ?
} CPU_t;
c代碼實現如下:
static CPU_t *cpus_refresh (CPU_t *cpus) ?
{ ?
? ?static FILE *fp = NULL; ?
? ?int i; ?
? ?int num; ?
? ?// enough for a /proc/stat CPU line (not the intr line) ?
? ?char buf[SMLBUFSIZ]; ?
??
? ?/* by opening this file once, we'll avoid the hit on minor page faults?
? ? ? (sorry Linux, but you'll have to close it for us) */ ?
? ?if (!fp) { ?
? ? ? if (!(fp = fopen("/proc/stat", "r"))) ?
? ? ? ? ?std_err(fmtmk("Failed /proc/stat open: %s", strerror(errno))); ?
? ? ? /* note: we allocate one more CPU_t than Cpu_tot so that the last slot?
? ? ? ? ? ? ? ?can hold tics representing the /proc/stat cpu summary (the first?
? ? ? ? ? ? ? ?line read) -- that slot supports our View_CPUSUM toggle */ ?
? ? ? cpus = alloc_c((1 + Cpu_tot) * sizeof(CPU_t)); ?
? ?} ?
? ?rewind(fp); ?
? ?fflush(fp); ?
??
? ?// first value the last slot with the cpu summary line ?
? ?if (!fgets(buf, sizeof(buf), fp)) std_err("failed /proc/stat read"); ?
? ?cpus[Cpu_tot].x = 0; ?// FIXME: can't tell by kernel version number ?
? ?cpus[Cpu_tot].y = 0; ?// FIXME: can't tell by kernel version number ?
? ?cpus[Cpu_tot].z = 0; ?// FIXME: can't tell by kernel version number ?
? ?num = sscanf(buf, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu", ?
? ? ? &cpus[Cpu_tot].u, ?
? ? ? &cpus[Cpu_tot].n, ?
? ? ? &cpus[Cpu_tot].s, ?
? ? ? &cpus[Cpu_tot].i, ?
? ? ? &cpus[Cpu_tot].w, ?
? ? ? &cpus[Cpu_tot].x, ?
? ? ? &cpus[Cpu_tot].y, ?
? ? ? &cpus[Cpu_tot].z ?
? ?); ?
? ?if (num < 4) ?
? ? ? ? ?std_err("failed /proc/stat read"); ?
??
? ?// and just in case we're 2.2.xx compiled without SMP support... ?
? ?if (Cpu_tot == 1) { ?
? ? ? cpus[1].id = 0; ?
? ? ? memcpy(cpus, &cpus[1], sizeof(CPU_t)); ?
? ?} ?
??
? ?// now value each separate cpu's tics ?
? ?for (i = 0; 1 < Cpu_tot && i < Cpu_tot; i++) { ?
? ? ? if (!fgets(buf, sizeof(buf), fp)) std_err("failed /proc/stat read"); ?
? ? ? cpus[i].x = 0; ?// FIXME: can't tell by kernel version number ?
? ? ? cpus[i].y = 0; ?// FIXME: can't tell by kernel version number ?
? ? ? cpus[i].z = 0; ?// FIXME: can't tell by kernel version number ?
? ? ? num = sscanf(buf, "cpu%u %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu", ?
? ? ? ? ?&cpus[i].id, ?
? ? ? ? ?&cpus[i].u, &cpus[i].n, &cpus[i].s, &cpus[i].i, &cpus[i].w, &cpus[i].x, &cpus[i].y, &cpus[i].z ?
? ? ? ); ?
? ? ? if (num < 4) ?
? ? ? ? ? ? std_err("failed /proc/stat read"); ?
? ?} ?
? ?return cpus; ?
} ?
c 代碼實現如下:
static void summaryhlp (CPU_t *cpu, const char *pfx) ?
{ ?
? ?// we'll trim to zero if we get negative time ticks, ?
? ?// which has happened with some SMP kernels (pre-2.4?) ?
#define TRIMz(x) ?((tz = (SIC_t)(x)) < 0 ? 0 : tz) ?
? ?SIC_t 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; ?
??
? ?// display some kinda' cpu state percentages ?
? ?// (who or what is explained by the passed prefix) ?
? ?show_special( ?
? ? ? 0, ?
? ? ? fmtmk( ?
? ? ? ? ?States_fmts, ?
? ? ? ? ?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 ?
? ? ? ) ?
? ?); ?
? ?Msg_row += 1; ?
??
? ?// remember for next time around ?
? ?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 ?
} ?
總結
以上是生活随笔為你收集整理的Linux Cpu 利用率计算的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 软件过程— 螺旋模型
- 下一篇: MySQL 基本语法