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

linuxc程序获取cpu使用率及内存使用情况

(2018-04-03 13:40:00)
分类: LINUX
from:http://blog.sina.com.cn/s/blog_49efd54001019r1j.html
想获取一下目标机运行时linux系统的硬件占用情况,写了这几个小程序,以后直接用了。
方法就是读取proc下的文件来获取了。 cpu使用率:    /proc/stat ,内存使用情况:      /proc/meminfo
看程序 

typedef struct PACKED         //定义一个cpu occupy的结构体
{
char name[20];      //定义一个char类型的数组名name有20个元素
unsigned int user; //定义一个无符号的int类型的user
unsigned int nice; //定义一个无符号的int类型的nice
unsigned int system;//定义一个无符号的int类型的system
unsigned int idle; //定义一个无符号的int类型的idle
}CPU_OCCUPY;

typedef struct PACKED         //定义一个mem occupy的结构体
{
char name[20];      //定义一个char类型的数组名name有20个元素
unsigned long total; 
char name2[20];
unsigned long free;                       
}MEM_OCCUPY;

get_memoccupy (MEM_OCCUPY *mem) //对无类型get函数含有一个形参结构体类弄的指针O
{
    FILE *fd;          
    int n;             
    char buff[256];   
    MEM_OCCUPY *m;
    m=mem;
                                                                                                              
    fd fopen ("/proc/meminfo", "r"); 
      
    fgets (buff, sizeof(buff), fd); 
    fgets (buff, sizeof(buff), fd); 
    fgets (buff, sizeof(buff), fd); 
    fgets (buff, sizeof(buff), fd); 
    sscanf (buff, "%s %u %s", m->name, &m->total, m->name2); 
    
    fgets (buff, sizeof(buff), fd); //从fd文件中读取长度为buff的字符串再存到起始地址为buff这个空间里 
    sscanf (buff, "%s %u", m->name2, &m->free, m->name2); 
    
    fclose(fd);     //关闭文件fd
}

int cal_cpuoccupy (CPU_OCCUPY *o, CPU_OCCUPY *n) 
  
    unsigned long od, nd;    
    unsigned long id, sd;
    int cpu_use 0;   
    
    od (unsigned long) (o->user o->nice o->system +o->idle);//第一次(用户+优先级+系统+空闲)的时间再赋给od
    nd (unsigned long) (n->user n->nice n->system +n->idle);//第二次(用户+优先级+系统+空闲)的时间再赋给od
      
    id (unsigned long) (n->user o->user);    //用户第一次和第二次的时间之差再赋给id
    sd (unsigned long) (n->system o->system);//系统第一次和第二次的时间之差再赋给sd
    if((nd-od) != 0)
    cpu_use (int)((sd+id)*10000)/(nd-od); //((用户+系统)乖100)除(第一次和第二次的时间差)再赋给g_cpu_used
    else cpu_use 0;
    //printf("cpu: %u/n",cpu_use);
    return cpu_use;
}

get_cpuoccupy (CPU_OCCUPY *cpust) //对无类型get函数含有一个形参结构体类弄的指针O
  
    FILE *fd;         
    int n;            
    char buff[256]; 
    CPU_OCCUPY *cpu_occupy;
    cpu_occupy=cpust;
                                                                                                               
    fd fopen ("/proc/stat", "r"); 
    fgets (buff, sizeof(buff), fd);
    
    sscanf (buff, "%s %u %u %u %u", cpu_occupy->name, &cpu_occupy->user, &cpu_occupy->nice,&cpu_occupy->system, &cpu_occupy->idle);
    
    fclose(fd);     
}

int main()
{
    CPU_OCCUPY cpu_stat1;
    CPU_OCCUPY cpu_stat2;
    MEM_OCCUPY mem_stat;
    int cpu;
    
    //获取内存
    get_memoccupy ((MEM_OCCUPY *)&mem_stat);
    
    //第一次获取cpu使用情况
    get_cpuoccupy((CPU_OCCUPY *)&cpu_stat1);
    sleep(10);
    
    //第二次获取cpu使用情况
    get_cpuoccupy((CPU_OCCUPY *)&cpu_stat2);
    
    //计算cpu使用率
    cpu cal_cpuoccupy ((CPU_OCCUPY *)&cpu_stat1, (CPU_OCCUPY *)&cpu_stat2);
    
    return 0;

 

 

 

想获取一下目标机运行时linux系统的硬件占用情况,写了这几个小程序,以后直接用了。
方法就是读取proc下的文件来获取了。 cpu使用率:    /proc/stat ,内存使用情况:      /proc/meminfo
看程序 

typedef struct PACKED         //定义一个cpu occupy的结构体
{
char name[20];      //定义一个char类型的数组名name有20个元素
unsigned int user; //定义一个无符号的int类型的user
unsigned int nice; //定义一个无符号的int类型的nice
unsigned int system;//定义一个无符号的int类型的system
unsigned int idle; //定义一个无符号的int类型的idle
}CPU_OCCUPY;

typedef struct PACKED         //定义一个mem occupy的结构体
{
char name[20];      //定义一个char类型的数组名name有20个元素
unsigned long total; 
char name2[20];
unsigned long free;                       
}MEM_OCCUPY;

get_memoccupy (MEM_OCCUPY *mem) //对无类型get函数含有一个形参结构体类弄的指针O
{
    FILE *fd;          
    int n;             
    char buff[256];   
    MEM_OCCUPY *m;
    m=mem;
                                                                                                              
    fd fopen ("/proc/meminfo", "r"); 
      
    fgets (buff, sizeof(buff), fd); 
    fgets (buff, sizeof(buff), fd); 
    fgets (buff, sizeof(buff), fd); 
    fgets (buff, sizeof(buff), fd); 
    sscanf (buff, "%s %u %s", m->name, &m->total, m->name2); 
    
    fgets (buff, sizeof(buff), fd); //从fd文件中读取长度为buff的字符串再存到起始地址为buff这个空间里 
    sscanf (buff, "%s %u", m->name2, &m->free, m->name2); 
    
    fclose(fd);     //关闭文件fd
}

int cal_cpuoccupy (CPU_OCCUPY *o, CPU_OCCUPY *n) 
  
    unsigned long od, nd;    
    unsigned long id, sd;
    int cpu_use 0;   
    
    od (unsigned long) (o->user o->nice o->system +o->idle);//第一次(用户+优先级+系统+空闲)的时间再赋给od
    nd (unsigned long) (n->user n->nice n->system +n->idle);//第二次(用户+优先级+系统+空闲)的时间再赋给od
      
    id (unsigned long) (n->user o->user);    //用户第一次和第二次的时间之差再赋给id
    sd (unsigned long) (n->system o->system);//系统第一次和第二次的时间之差再赋给sd
    if((nd-od) != 0)
    cpu_use (int)((sd+id)*10000)/(nd-od); //((用户+系统)乖100)除(第一次和第二次的时间差)再赋给g_cpu_used
    else cpu_use 0;
    //printf("cpu: %u/n",cpu_use);
    return cpu_use;
}

get_cpuoccupy (CPU_OCCUPY *cpust) //对无类型get函数含有一个形参结构体类弄的指针O
  
    FILE *fd;         
    int n;            
    char buff[256]; 
    CPU_OCCUPY *cpu_occupy;
    cpu_occupy=cpust;
                                                                                                               
    fd fopen ("/proc/stat", "r"); 
    fgets (buff, sizeof(buff), fd);
    
    sscanf (buff, "%s %u %u %u %u", cpu_occupy->name, &cpu_occupy->user, &cpu_occupy->nice,&cpu_occupy->system, &cpu_occupy->idle);
    
    fclose(fd);     
}

int main()
{
    CPU_OCCUPY cpu_stat1;
    CPU_OCCUPY cpu_stat2;
    MEM_OCCUPY mem_stat;
    int cpu;
    
    //获取内存
    get_memoccupy ((MEM_OCCUPY *)&mem_stat);
    
    //第一次获取cpu使用情况
    get_cpuoccupy((CPU_OCCUPY *)&cpu_stat1);
    sleep(10);
    
    //第二次获取cpu使用情况
    get_cpuoccupy((CPU_OCCUPY *)&cpu_stat2);
    
    //计算cpu使用率
    cpu cal_cpuoccupy ((CPU_OCCUPY *)&cpu_stat1, (CPU_OCCUPY *)&cpu_stat2);
    
    return 0;

 

 

 

我们在搞性能测试的时候,对后台服务器的CPU利用率监控是一个常用的手段。服务器的CPU利用率高,则表明服务器很繁忙。如果前台响应时间越来越大,而后台CPU利用率始终上不去,说明在某个地方有瓶颈了,系统需要调优。这个是即使不懂技术的人都容易理解的事情。

上面理解对吗?我个人觉得不十分准确。这个要看后台你测试的进程是什么类型的。如果是计算密集型的进程,当前端压力越来越大的时候,很容易把CPU 利用率打上去。但是如果是I/O网络密集型的进程,即使客户端的请求越来越多,但是服务器CPU不一定能上去,这个是你要测试的进程的自然属性决定的。比较常见的就是,大文件频繁读写的cpu开销远小于小文件频繁读写的开销。因为在I/O吞吐量一定时,小文件的读写更加频繁,需要更多的cpu来处理I/O 的中断。

在Linux/Unix下,CPU利用率分为用户态系统态空闲态,分别表示CPU处于用户态执行的时间,系统内核执行的时间,和空闲系统进程执行的时间。平时所说的CPU利用率是指:CPU执行非系统空闲进程的时间 CPU总的执行时间

在Linux的内核中,有一个全局变量:Jiffies。 Jiffies代表时间。它的单位随硬件平台的不同而不同。系统里定义了一个常数HZ,代表每秒种最小时间间隔的数目。这样jiffies的单位就是 1/HZ。Intel平台jiffies的单位是1/100秒,这就是系统所能分辨的最小时间间隔了。每个CPU时间片,Jiffies都要加1。 CPU的利用率就是用执行用户态+系统态的Jiffies除以总的Jifffies来表示。

在Linux系统中,可以用/proc/stat文件来计算cpu的利用率(详细的解释可参考:http: //www.linuxhowtos.org/System/procstat.htm)。这个文件包含了所有CPU活动的信息,该文件中的所有值都是从系统启动开始累计到当前时刻。

如:


  1. [sailorhzr@builder ~]$ cat /proc/stat  
  2. cpu 432661 13295 86656 422145968 171474 233 5346 
  3. cpu123075 2462 23494 105543694 16586 4615 
  4. cpu111917 4124 23858 105503820 69697 123 371 
  5. cpu103164 3554 21530 105521167 64032 106 334 
  6. cpu94504 3153 17772 105577285 21158 24 
  7. intr 1065711094 1057275779 92 0 6 4 3527 0 70 20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7376958 0 0 0 0 1054602 0 0 0 0 30 0 0 0 0 0 0 0 0 0 0 0 
  8. ctxt 19067887 
  9. btime 1139187531 
  10. processes 270014 
  11. procs_running 1 
  12. procs_blocked 0   
  13.  

输出解释

CPU 以及CPU0、CPU1、CPU2、CPU3每行的每个参数意思(以第一行为例)为:

 

参数 解释
user (432661) 

nice (13295) 

system (86656) 
idle (422145968) 

iowait (171474) 

irq (233) 
softirq (5346) 
 
从系统启动开始累计到当前时刻,用户态的CPU时间(单位:jiffies) ,不包含 nice值为负进程。1jiffies=0.01秒
从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间(单位:jiffies)
从系统启动开始累计到当前时刻,核心时间(单位:jiffies)
从系统启动开始累计到当前时刻,除硬盘IO等待时间以外其它等待时间(单位:jiffies)
从系统启动开始累计到当前时刻,硬盘IO等待时间(单位:jiffies) 
从系统启动开始累计到当前时刻,硬中断时间(单位:jiffies)
从系统启动开始累计到当前时刻,软中断时间(单位:jiffies) 

 

CPU时间=user+system+nice+idle+iowait+irq+softirq

“intr”这行给出中断的信息,第一个为自系统启动以来,发生的所有的中断的次数;然后每个数对应一个特定的中断自系统启动以来所发生的次数。

“ctxt”给出了自系统启动以来CPU发生的上下文交换的次数。

“btime”给出了从系统启动到现在为止的时间,单位为秒。

“processes (total_forks) 自系统启动以来所创建的任务的个数目。

“procs_running”:当前运行队列的任务的数目。

“procs_blocked”:当前被阻塞的任务的数目。

那么CPU利用率可以使用以下两个方法。先取两个采样点,然后计算其差值:


  1. cpu usage=(idle2-idle1)/(cpu2-cpu1)*100 
  2. cpu usage=[(user_2 +sys_2+nice_2(user_1 sys_1+nice_1)]/(total_2 total_1)*100 
  3.  

以下用分别用bash和perl做的一个cpu利用率的计算:

本人注:以下代码则采用公式为:


  1. total_0USER[0]+NICE[0]+SYSTEM[0]+IDLE[0]+IOWAIT[0]+IRQ[0]+SOFTIRQ[0 
  2. total_1=USER[1]+NICE[1]+SYSTEM[1]+IDLE[1]+IOWAIT[1]+IRQ[1]+SOFTIRQ[1 
  3. cpu usage=(IDLE[0]-IDLE[1]) (total_0-total_1100 
  4.  

###bash 代码


  1. CODE:#!/bin/sh  
  2.  
  3. ##echo user nice system idle iowait irq softirq  
  4. CPULOG_1=$(cat /proc/stat grep 'cpu ' awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}' 
  5. SYS_IDLE_1=$(echo $CPULOG_1 awk '{print $4}' 
  6. Total_1=$(echo $CPULOG_1 awk '{print $1+$2+$3+$4+$5+$6+$7}' 
  7.  
  8. sleep  
  9.  
  10. CPULOG_2=$(cat /proc/stat grep 'cpu ' awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}' 
  11. SYS_IDLE_2=$(echo $CPULOG_2 awk '{print $4}' 
  12. Total_2=$(echo $CPULOG_2 awk '{print $1+$2+$3+$4+$5+$6+$7}' 
  13.  
  14. SYS_IDLE=`expr $SYS_IDLE_2 $SYS_IDLE_1 
  15.  
  16. Total=`expr $Total_2 $Total_1 
  17. SYS_USAGE=`expr $SYS_IDLE/$Total*100 |bc -l`  
  18.  
  19. SYS_Rate=`expr 100-$SYS_USAGE |bc -l`  
  20.  
  21. Disp_SYS_Rate=`expr "scale=3; $SYS_Rate/1" |bc`  
  22. echo $Disp_SYS_Rate 
  23.  
  24.    

###perl 代码


  1. #!/usr/bin/perl  
  2.  
  3. use warnings;  
  4.  
  5. $SLEEPTIME=5;  
  6.  
  7. if (-e "/tmp/stat" 
  8. unlink "/tmp/stat" 
  9.  
  10. open (JIFF_TMP, ">>/tmp/stat"|| die "Can't open /proc/stat file!/n" 
  11. open (JIFF, "/proc/stat"|| die "Can't open /proc/stat file!/n" 
  12. @jiff_0=;  
  13. print JIFF_TMP $jiff_0[0]  
  14. close (JIFF);  
  15.  
  16. sleep $SLEEPTIME 
  17.  
  18. open (JIFF, "/proc/stat"|| die "Can't open /proc/stat file!/n" 
  19. @jiff_1=;  
  20. print JIFF_TMP $jiff_1[0];  
  21. close (JIFF);  
  22. close (JIFF_TMP);  
  23.  
  24. @USER=`awk '{print /$2}' "/tmp/stat"`;  
  25. @NICE=`awk '{print /$3}' "/tmp/stat"`;  
  26. @SYSTEM=`awk '{print /$4}' "/tmp/stat"`;  
  27. @IDLE=`awk '{print /$5}' "/tmp/stat"`;  
  28. @IOWAIT=`awk '{print /$6}' "/tmp/stat"`;  
  29. @IRQ=`awk '{print /$7}' "/tmp/stat"`;  
  30. @SOFTIRQ=`awk '{print /$8}' "/tmp/stat"`;  
  31.  
  32. $JIFF_0=$USER[0]+$NICE[0]+$SYSTEM[0]+$IDLE[0]+$IOWAIT[0]+$IRQ[0]+$SOFTIRQ[0];  
  33. $JIFF_1=$USER[1]+$NICE[1]+$SYSTEM[1]+$IDLE[1]+$IOWAIT[1]+$IRQ[1]+$SOFTIRQ[1];  
  34.  
  35. $SYS_IDLE=($IDLE[0]-$IDLE[1]) ($JIFF_0-$JIFF_1100;  
  36. $SYS_USAGE=100 $SYS_IDLE 
  37.  
  38. printf ("The CPU usage is %1.2f%%/n",$SYS_USAGE);

0

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

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

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

新浪公司 版权所有