zoukankan      html  css  js  c++  java
  • linux下用/proc/stat文件来计算cpu的利用率-c语言实现

    proc文件系统介绍

          /proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为内核与进程提供通信的接口。用户和应用程序可以通过/proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息,如进程,是动态改变的,所以用户或应用程序读取/proc目录中的文件时,proc文件系统是动态从系统内核读出所需信息并提交的。

        /proc目录中有一些以数字命名的目录,它们是进程目录。系统中当前运行的每一个进程在/proc下都对应一个以进程号为目录名的目录/proc/pid,它们是读取进程信息的接口。此外,在Linux2.6.0-test6以上的版本中/proc/pid目录中有一个task目录,/proc/pid/task目录中也有一些以该进程所拥有的线程的线程号命名的目录/proc/pid/task/tid,它们是读取线程信息的接口。

    /proc/stat文件

    1. [root@root c_study]# cat /proc/stat   
    2. cpu  15579 99 13680 698457 10939 40 651 0 0  
    3. cpu0 1669 7 1974 338065 1396 5 9 0 0  
    4. cpu1 13910 91 11705 360391 9542 35 641 0 0  
    5. intr 957831 163 8 0 1 1 0 5 0 1 0 0 0 101 0 0 3582 0 37804 3657 22410 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0  
    6. ctxt 501479  
    7. btime 1363495431  
    8. processes 40101  
    9. procs_running 1  
    10. procs_blocked 0  
    11. softirq 1396087 0 693403 12972 15932 35928 3 44577 479 592793  
    12. [root@root c_study]#   

    第一行的数值表示的是CPU总的使用情况,所以我们只要用第一行的数字计算就可以了。下表解析第一行各数值的含义:

    参数          解析(单位:jiffies)

    (jiffies是内核中的一个全局变量,用来记录自系统启动一来产生的节拍数,在linux中,一个节拍大致可理解为操作系统进程调度的最小时间片,不同linux内核可能值有不同,通常在1ms到10ms之间)

    user ( 15579 )    从系统启动开始累计到当前时刻,处于用户态的运行时间,不包含 nice值为负进程。

    nice (99)      从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间

    system (13680)  从系统启动开始累计到当前时刻,处于核心态的运行时间

    idle (698457)   从系统启动开始累计到当前时刻,除IO等待时间以外的其它等待时间

    iowait (10939) 从系统启动开始累计到当前时刻,IO等待时间(since 2.5.41)

    irq (40)           从系统启动开始累计到当前时刻,硬中断时间(since 2.6.0-test4)

    softirq (651)      从系统启动开始累计到当前时刻,软中断时间(since 2.6.0-test4)

    stealstolen(0)     which is the time spent in other operating systems when running in a virtualized environment(since 2.6.11)

    guest(0)        which is the time spent running a virtual  CPU  for  guest operating systems under the control of the Linux kernel(since 2.6.24)

     结论:总的cpu时间totalCpuTime = user + nice + system + idle + iowait + irq + softirq + stealstolen +guest

      

    /proc/<pid>/stat文件                                          

    该文件包含了某一进程所有的活动的信息,该文件中的所有值都是从系统启动开始累计

    到当前时刻。以下通过实例数据来说明该文件中各字段的含义。

    [zhengangen@buick ~]# cat /proc/6873/stat

    6873 (a.out) R 6723 6873 6723 34819 6873 8388608 77 0 0 0 41958 31 0 0 25 0 3 0 5882654 1409024 56 4294967295 134512640 134513720 3215579040 0 2097798 0 0 0 0 0 0 0 17 0 0 0

    说明:以下只解释对我们计算Cpu使用率有用相关参数

    参数                                                                解释

    pid=6873                            进程号

    utime=1587                       该任务在用户态运行的时间,单位为jiffies

    stime=41958                      该任务在核心态运行的时间,单位为jiffies

    cutime=0                            所有已死线程在用户态运行的时间,单位为jiffies

    cstime=0                            所有已死在核心态运行的时间,单位为jiffies

    结论:进程的总Cpu时间processCpuTime = utime + stime + cutime + cstime,该值包括其所有线程的cpu时间。

    /proc/<pid>/task/<tid>/stat文件

     该文件包含了某一进程所有的活动的信息,该文件中的所有值都是从系统启动开始累计到当前时刻。该文件的内容格式以及各字段的含义同/proc/<pid>/stat文件。

             注意,该文件中的tid字段表示的不再是进程号,而是linux中的轻量级进程(lwp),即我们通常所说的线程。

    结论:线程Cpu时间threadCpuTime = utime + stime

    总的Cpu使用率计算

    计算方法:

    1、  采样两个足够短的时间间隔的Cpu快照,分别记作t1,t2,其中t1、t2的结构均为:

    (user、nice、system、idle、iowait、irq、softirq、stealstolen、guest)的9元组;

    2、  计算总的Cpu时间片totalCpuTime

    a)         把第一次的所有cpu使用情况求和,得到s1;

    b)         把第二次的所有cpu使用情况求和,得到s2;

    c)         s2 - s1得到这个时间间隔内的所有时间片,即totalCpuTime = j2 - j1 ;

    3、计算空闲时间idle

    idle对应第四列的数据,用第二次的idle - 第一次的idle即可

    idle=第二次的idle - 第一次的idle

    4、计算cpu使用率

    pcpu =100* (total-idle)/total

    5、同理可以用同样的方法求出其他进程和线程所占cpu资源

    源码

    1. #include<stdio.h>  
    2. #include<stdlib.h>  
    3. #include<string.h>  
    4.   
    5. #define __DEBUG__ 1  
    6. #define CK_TIME 1  
    7.   
    8. int main(int argc ,char *argv[])  
    9. {  
    10.         FILE *fp;  
    11.         char buf[128];  
    12.         char cpu[5];  
    13.         long int user,nice,sys,idle,iowait,irq,softirq;  
    14.   
    15.         long int all1,all2,idle1,idle2;  
    16.         float usage;  
    17.   
    18.         while(1)  
    19.         {  
    20.                 fp = fopen("/proc/stat","r");  
    21.                 if(fp == NULL)  
    22.                 {  
    23.                         perror("fopen:");  
    24.                         exit (0);  
    25.                 }  
    26.   
    27.   
    28.                 fgets(buf,sizeof(buf),fp);  
    29. #if __DEBUG__  
    30.                 printf("buf=%s",buf);  
    31. #endif  
    32.                 sscanf(buf,"%s%d%d%d%d%d%d%d",cpu,&user,&nice,&sys,&idle,&iowait,&irq,&softirq);  
    33.                 /* 
    34. #if __DEBUG__ 
    35. printf("%s,%d,%d,%d,%d,%d,%d,%d ",cpu,user,nice,sys,idle,iowait,irq,softirq); 
    36. #endif 
    37. */  
    38.                 all1 = user+nice+sys+idle+iowait+irq+softirq;  
    39.                 idle1 = idle;  
    40.                 rewind(fp);  
    41.                 /*第二次取数据*/  
    42.                 sleep(CK_TIME);  
    43.                 memset(buf,0,sizeof(buf));  
    44.                 cpu[0] = '';  
    45.                 user=nice=sys=idle=iowait=irq=softirq=0;  
    46.                 fgets(buf,sizeof(buf),fp);  
    47. #if __DEBUG__  
    48.                 printf("buf=%s",buf);  
    49. #endif  
    50.                 sscanf(buf,"%s%d%d%d%d%d%d%d",cpu,&user,&nice,&sys,&idle,&iowait,&irq,&softirq);  
    51.                 /* 
    52. #if __DEBUG__ 
    53. printf("%s,%d,%d,%d,%d,%d,%d,%d ",cpu,user,nice,sys,idle,iowait,irq,softirq); 
    54. #endif 
    55. */  
    56.                 all2 = user+nice+sys+idle+iowait+irq+softirq;  
    57.                 idle2 = idle;  
    58.   
    59.                 usage = (float)(all2-all1-(idle2-idle1)) / (all2-all1)*100 ;  
    60.   
    61.   
    62.                 printf("all=%d ",all2-all1);  
    63.                 printf("ilde=%d ",all2-all1-(idle2-idle1));  
    64.                 printf("cpu use = %.2f\% ",usage);  
    65.                 printf("======================= ");  
    66.   
    67.                 fclose(fp);  
    68.         }  
    69.         return 1;  
    70. }  

    gcc编译

     
    1. gcc -o cpu_use -g cpu_use.c   


    运行

     
     
      1. buf=cpu  15824 100 13772 879622 11014 40 720 0 0  
      2. buf=cpu  15837 100 13790 879731 11014 40 720 0 0  
      3. all=140  
      4. ilde=31  
      5. cpu use = 22.14%  
      6. =======================  
      7. buf=cpu  15837 100 13790 879731 11014 40 720 0 0  
      8. buf=cpu  15857 100 13824 879786 11014 40 721 0 0  
      9. all=110  
      10. ilde=55  
      11. cpu use = 50.00%  
      12. =======================  
      13. buf=cpu  15857 100 13824 879786 11014 40 721 0 0  
      14. buf=cpu  15877 100 13856 879842 11014 41 721 0 0  
      15. all=109  
      16. ilde=53  
      17. cpu use = 48.62%  
      18. =======================  
      19. buf=cpu  15877 100 13857 879842 11014 41 721 0 0  
      20. buf=cpu  15897 100 13889 879901 11014 41 722 0 0  
      21. all=112  
      22. ilde=53  
      23. cpu use = 47.32%  
      24. =======================  

    转自:https://blog.csdn.net/stormbjm/article/details/19202849

  • 相关阅读:
    著名的小退问题
    Oracle学习笔记(十二)
    Oracle学习笔记(十一)
    Oracle学习笔记(十)
    Oracle学习笔记(九)
    Oracle学习笔记(八)
    Oracle学习笔记(七)
    Oracle学习笔记(六)
    Oracle学习笔记(五)
    Oracle学习笔记(四)
  • 原文地址:https://www.cnblogs.com/liushui-sky/p/9258101.html
Copyright © 2011-2022 走看看