Chinaunix首页 | 论坛 | 博客

13

  • 博客访问: 239640
  • 博文数量: 26
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 1000
  • 用 户 组: 普通用户
  • 注册时间: 2004-10-15 23:24
文章分类

全部博文(26)

文章存档

2011年(1)

2010年(1)

2009年(7)

2008年(17)

我的朋友

分类:

2008-11-25 17:27:17

转自:http://wildwind.javaeye.com/blog/69944

Linux Cpu 利用率计算

前几天要写一个取得linux performance的函数。查询了一些资料。发现有几种计算cpu利用率的方法。但是都不怎么正确。最后查了以下top的源代码。现列出其计算cpu利用率的关键函数
c 代码
 
  1. typedef struct CPU_t {  
  2.    TIC_t u, n, s, i, w, x, y, z; // as represented in /proc/stat  
  3.    TIC_t u_sav, s_sav, n_sav, i_sav, w_sav, x_sav, y_sav, z_sav; // in the order of our display  
  4.    unsigned id;  // the CPU ID number  
  5. } CPU_t;  
c 代码
  1. static CPU_t *cpus_refresh (CPU_t *cpus)  
  2. {  
  3.    static FILE *fp = NULL;  
  4.    int i;  
  5.    int num;  
  6.    // enough for a /proc/stat CPU line (not the intr line)  
  7.    char buf[SMLBUFSIZ];  
  8.   
  9.    /* by opening this file once, we'll avoid the hit on minor page faults 
  10.       (sorry Linux, but you'll have to close it for us) */  
  11.    if (!fp) {  
  12.       if (!(fp = fopen("/proc/stat""r")))  
  13.          std_err(fmtmk("Failed /proc/stat open: %s", strerror(errno)));  
  14.       /* note: we allocate one more CPU_t than Cpu_tot so that the last slot 
  15.                can hold tics representing the /proc/stat cpu summary (the first 
  16.                line read) -- that slot supports our View_CPUSUM toggle */  
  17.       cpus = alloc_c((1 + Cpu_tot) * sizeof(CPU_t));  
  18.    }  
  19.    rewind(fp);  
  20.    fflush(fp);  
  21.   
  22.    // first value the last slot with the cpu summary line  
  23.    if (!fgets(buf, sizeof(buf), fp)) std_err("failed /proc/stat read");  
  24.    cpus[Cpu_tot].x = 0;  // FIXME: can't tell by kernel version number  
  25.    cpus[Cpu_tot].y = 0;  // FIXME: can't tell by kernel version number  
  26.    cpus[Cpu_tot].z = 0;  // FIXME: can't tell by kernel version number  
  27.    num = sscanf(buf, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",  
  28.       &cpus[Cpu_tot].u,  
  29.       &cpus[Cpu_tot].n,  
  30.       &cpus[Cpu_tot].s,  
  31.       &cpus[Cpu_tot].i,  
  32.       &cpus[Cpu_tot].w,  
  33.       &cpus[Cpu_tot].x,  
  34.       &cpus[Cpu_tot].y,  
  35.       &cpus[Cpu_tot].z  
  36.    );  
  37.    if (num < 4)  
  38.          std_err("failed /proc/stat read");  
  39.   
  40.    // and just in case we're 2.2.xx compiled without SMP support...  
  41.    if (Cpu_tot == 1) {  
  42.       cpus[1].id = 0;  
  43.       memcpy(cpus, &cpus[1], sizeof(CPU_t));  
  44.    }  
  45.   
  46.    // now value each separate cpu's tics  
  47.    for (i = 0; 1 < Cpu_tot && i < Cpu_tot; i++) {  
  48.       if (!fgets(buf, sizeof(buf), fp)) std_err("failed /proc/stat read");  
  49.       cpus[i].x = 0;  // FIXME: can't tell by kernel version number  
  50.       cpus[i].y = 0;  // FIXME: can't tell by kernel version number  
  51.       cpus[i].z = 0;  // FIXME: can't tell by kernel version number  
  52.       num = sscanf(buf, "cpu%u %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",  
  53.          &cpus[i].id,  
  54.          &cpus[i].u, &cpus[i].n, &cpus[i].s, &cpus[i].i, &cpus[i].w, &cpus[i].x, &cpus[i].y, &cpus[i].z  
  55.       );  
  56.       if (num < 4)  
  57.             std_err("failed /proc/stat read");  
  58.    }  
  59.    return cpus;  

c 代码
 
  1. static void summaryhlp (CPU_t *cpu, const char *pfx)  
  2. {  
  3.    // we'll trim to zero if we get negative time ticks,  
  4.    // which has happened with some SMP kernels (pre-2.4?)  
  5. #define TRIMz(x)  ((tz = (SIC_t)(x)) < 0 ? 0 : tz)  
  6.    SIC_t u_frme, s_frme, n_frme, i_frme, w_frme, x_frme, y_frme, z_frme, tot_frme, tz;  
  7.    float scale;  
  8.   
  9.    u_frme = cpu->u - cpu->u_sav;  
  10.    s_frme = cpu->s - cpu->s_sav;  
  11.    n_frme = cpu->n - cpu->n_sav;  
  12.    i_frme = TRIMz(cpu->i - cpu->i_sav);  
  13.    w_frme = cpu->w - cpu->w_sav;  
  14.    x_frme = cpu->x - cpu->x_sav;  
  15.    y_frme = cpu->y - cpu->y_sav;  
  16.    z_frme = cpu->z - cpu->z_sav;  
  17.    tot_frme = u_frme + s_frme + n_frme + i_frme + w_frme + x_frme + y_frme + z_frme;  
  18.    if (tot_frme < 1) tot_frme = 1;  
  19.    scale = 100.0 / (float)tot_frme;  
  20.   
  21.    // display some kinda' cpu state percentages  
  22.    // (who or what is explained by the passed prefix)  
  23.    show_special(  
  24.       0,  
  25.       fmtmk(  
  26.          States_fmts,  
  27.          pfx,  
  28.          (float)u_frme * scale,  
  29.          (float)s_frme * scale,  
  30.          (float)n_frme * scale,  
  31.          (float)i_frme * scale,  
  32.          (float)w_frme * scale,  
  33.          (float)x_frme * scale,  
  34.          (float)y_frme * scale,  
  35.          (float)z_frme * scale  
  36.       )  
  37.    );  
  38.    Msg_row += 1;  
  39.   
  40.    // remember for next time around  
  41.    cpu->u_sav = cpu->u;  
  42.    cpu->s_sav = cpu->s;  
  43.    cpu->n_sav = cpu->n;  
  44.    cpu->i_sav = cpu->i;  
  45.    cpu->w_sav = cpu->w;  
  46.    cpu->x_sav = cpu->x;  
  47.    cpu->y_sav = cpu->y;  
  48.    cpu->z_sav = cpu->z;  
  49.   
  50. #undef TRIMz  

阅读(2112) | 评论(0) | 转发(0) |
0

上一篇:/proc/stat

下一篇:Eclipse常用的快捷键

给主人留下些什么吧!~~