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  
}  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值