加载中…
个人资料
BLUESEA
BLUESEA
  • 博客等级:
  • 博客积分:0
  • 博客访问:3,240
  • 关注人气:35
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

linux下用/proc/stat文件来计算cpu的利用率(附源码)

(2013-07-22 14:58:10)
分类: linux学习笔记

(转)

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


该文件包含了某一进程所有的活动的信息,该文件中的所有值都是从系统启动开始累计到当前时刻。该文件的内容格式以及各字段的含义同/proc//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   
  2. #include   
  3. #include   
  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.                 all1 user+nice+sys+idle+iowait+irq+softirq;  
  35.                 idle1 idle;  
  36.                 rewind(fp);  
  37.                   
  38.                 sleep(CK_TIME);  
  39.                 memset(buf,0,sizeof(buf));  
  40.                 cpu[0] '\0' 
  41.                 user=nice=sys=idle=iowait=irq=softirq=0;  
  42.                 fgets(buf,sizeof(buf),fp);  
  43. #if __DEBUG__   
  44.                 printf("buf=%s",buf);  
  45. #endif   
  46.                 sscanf(buf,"%s%d%d%d%d%d%d%d",cpu,&user,&nice,&sys,&idle,&iowait,&irq,&softirq);  
  47.                   
  48.                 all2 user+nice+sys+idle+iowait+irq+softirq;  
  49.                 idle2 idle;  
  50.   
  51.                 usage (float)(all2-all1-(idle2-idle1)) (all2-all1)*100  
  52.   
  53.   
  54.                 printf("all=%d\n",all2-all1);  
  55.                 printf("ilde=%d\n",all2-all1-(idle2-idle1));  
  56.                 printf("cpu use %.2f\%\n",usage);  
  57.                 printf("=======================\n");  
  58.   
  59.                 fclose(fp);  
  60.          
  61.         return 1;  
  62.  
#include
#include
#include

#define __DEBUG__ 1
#define CK_TIME 1

int main(int argc ,char *argv[])
{
        FILE *fp;
        char buf[128];
        char cpu[5];
        long int user,nice,sys,idle,iowait,irq,softirq;

        long int all1,all2,idle1,idle2;
        float usage;

        while(1)
        {
                fp = fopen("/proc/stat","r");
                if(fp == NULL)
                {
                        perror("fopen:");
                        exit (0);
                }


                fgets(buf,sizeof(buf),fp);
#if __DEBUG__
                printf("buf=%s",buf);
#endif
                sscanf(buf,"%s%d%d%d%d%d%d%d",cpu,&user,&nice,&sys,&idle,&iowait,&irq,&softirq);
                
                all1 = user+nice+sys+idle+iowait+irq+softirq;
                idle1 = idle;
                rewind(fp);
                
                sleep(CK_TIME);
                memset(buf,0,sizeof(buf));
                cpu[0] = '\0';
                user=nice=sys=idle=iowait=irq=softirq=0;
                fgets(buf,sizeof(buf),fp);
#if __DEBUG__
                printf("buf=%s",buf);
#endif
                sscanf(buf,"%s%d%d%d%d%d%d%d",cpu,&user,&nice,&sys,&idle,&iowait,&irq,&softirq);
                
                all2 = user+nice+sys+idle+iowait+irq+softirq;
                idle2 = idle;

                usage = (float)(all2-all1-(idle2-idle1)) / (all2-all1)*100 ;


                printf("all=%d\n",all2-all1);
                printf("ilde=%d\n",all2-all1-(idle2-idle1));
                printf("cpu use = %.2f\%\n",usage);
                printf("=======================\n");

                fclose(fp);
        }
        return 1;
}
gcc编译
  1. gcc -o cpu_use -g cpu_use.c   
gcc -o cpu_use -g cpu_use.c 

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

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有