linux有top命令可以直接查看cpu,内存等的信息,所以一开始想用top命令,把top命令中的输出信息截取对应的字符即可,但top命令默认只显示所有cpu总体的情况,要再按1才能显示每个cpu的情况,由于没有找到一种方法让top命令默认显示所有(网上看到可以修改配置,这样代码的移植性比较弱),本文直接从文件中读取对应的信息让后再计算。

在Linux系统中,可以用/proc/stat文件来计算cpu的利用率。这个文件包含了所有CPU活动的信息,该文件中的所有值都是从系统启动开始累计到当前时刻。

cpu信息文件:/proc/stat

cat /proc/stat
cpu 337712134 1302 739335470 2690662409 11683573 128 320721 0 0 0
cpu0 55063219 338 94747325 318411768 4082899 41 131156 0 0 0
cpu1 59899439 534 92379019 318004740 2031487 87 156022 0 0 0
cpu2 41417611 142 90909679 338163935 1942791 0 6239 0 0 0
cpu3 40957916 141 92700300 337612403 1193646 0 8844 0 0 0
cpu4 36417255 80 94021195 341204521 823278 0 5347 0 0 0
cpu5 35469507 39 91532676 344734322 730538 0 5046 0 0 0
cpu6 34362931 9 92062532 345606879 439086 0 3853 0 0 0
cpu7 34124252 18 90982740 346923837 439844 0 4210 0 0 0
intr 12221370344 15794 0 0 1 1 0 0 0 23 0 0 0 0 0 0 0 0 0 0 0 0 0 32 113 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 70286454 3019748 2 132782493 98452730 85396760 98138556 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 17244664282
btime 1374229384
processes 22325397
procs_running 4
procs_blocked 1
softirq 5575312221 0 3081978388 945064 587844502 71770833 0 70254703 329899248 634533 1431984950

输出解释

CPU 以及CPU0、CPU1、CPU2、CPU3、CPU4、CPU5、CPU6、CPU7每行的每个参数意思为:

参数 解释

user : 从系统启动开始累计到当前时刻,用户态的CPU时间(单位:jiffies) ,不包含 nice值为负进程。1jiffies=0.01秒

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

system : 从系统启动开始累计到当前时刻,核心时间(单位:jiffies)

idle : 从系统启动开始累计到当前时刻,除硬盘IO等待时间以外其它等待时间(单位:jiffies)

iowait :从系统启动开始累计到当前时刻,硬盘IO等待时间(单位:jiffies) ,

irq : 从系统启动开始累计到当前时刻,硬中断时间(单位:jiffies)

softirq :从系统启动开始累计到当前时刻,软中断时间(单位:jiffies)

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

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

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

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

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

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

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

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

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

内存信息文件:/proc/meminfo

cat /proc/meminfo
MemTotal: 2052440 kB //总内存
MemFree: 50004 kB
//空闲内存
Buffers: 19976 kB
//给文件的缓冲大小
Cached: 436412 kB
//高速缓冲存储器(http://baike.baidu.com/view/496990.htm)使用的大小
SwapCached: 19864 kB
//被高速缓冲存储用的交换空间大小
Active: 1144512 kB
//活跃使用中的高速缓冲存储器页面文件大小
Inactive: 732788 kB
//不经常使用的高速缓冲存储器页面文件大小
Active(anon): 987640 kB //anon:不久
Inactive(anon): 572512 kB
Active(file): 156872 kB
Inactive(file): 160276 kB
Unevictable: 8 kB
Mlocked: 8
kB
HighTotal: 1177160 kB //The total and
free amount of memory, in kilobytes, that is not directly mapped
into kernel space.
HighFree: 7396 kB // The
HighTotal value can vary based on the type of kernel used.
LowTotal: 875280 kB // The total
and free amount of memory, in kilobytes, that is directly mapped
into kernel space. used.
LowFree: 42608 kB //The
LowTotal value can vary based on the type of kernel
SwapTotal: 489940 kB
//交换空间总大小
SwapFree: 450328 kB //空闲交换空间
Dirty: 104 kB
//等待被写回到磁盘的大小
Writeback: 0 kB
//正在被写回的大小
AnonPages: 1408256 kB //未映射的页的大小
Mapped: 131964 kB
//设备和文件映射的大小
Slab: 37368
kB //内核数据结构缓存的大小,可减少申请和释放内存带来的消耗
SReclaimable: 14164 kB //可收回slab的大小
SUnreclaim: 23204 kB
//不可收回的slab的大小23204+14164=37368
PageTables: 13308 kB
//管理内存分页的索引表的大小
NFS_Unstable: 0 kB
//不稳定页表的大小
Bounce:
0 kB
//bounce:退回
WritebackTmp: 0 kB //
CommitLimit: 1516160 kB
Committed_AS: 2511900 kB
VmallocTotal: 122880 kB //虚拟内存大小
VmallocUsed: 28688 kB
//已经被使用的虚拟内存大小
VmallocChunk: 92204 kB
HugePages_Total: 0 //大页面的分配
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 10232 kB
DirectMap2M: 899072 kB
根据这些文件,写了个读取cpu和内存信息的代码
源码如下:
-----------------------cpu-------------------------------------------------------
#include 
#include 
#include
 #include 
int SysCpu()
{
const int MAX_LEN=256;
char sInfo[MAX_LEN];
char strInfo[1024];
// 最大处理器
const int MAX_PROCESSOR = 128;
int cpuNum = 0;//CPU个数
// CPU
float fCpuRate;
double cpu_idle = -1;
double cpu_sys = -1;
double cpu_user = -1;
double cpu_total = -1;
double cpu_wait = -1;
char name[8];
long int
user,nice,sys,idle,iowait,irq,softirq;
long int
userNext,niceNext,sysNext,idleNext,iowaitNext,irqNext,softirqNext;
FILE *fp;
char buf[MAX_PROCESSOR+1][128];
char bufNext[MAX_PROCESSOR+1][128];
int i = 0;
memset(sInfo, 0x00, sizeof(sInfo));
memset(strInfo, 0x00, sizeof(strInfo));
// 获取处理器数量
cpuNum = sysconf(_SC_NPROCESSORS_CONF);
if (cpuNum > MAX_PROCESSOR)
{
cpuNum =MAX_PROCESSOR;
}
//读取文件中cpu信息
fp = fopen("/proc/stat","r");
if(fp == NULL)
{
perror("fopen:");
return -1;
}
for (i=0; i
{
fgets(buf[i],sizeof(buf[i]),fp);
}
sleep(1);
rewind(fp);
for (i=0; i
{
fgets(bufNext[i],sizeof(bufNext[i]),fp);
}
fclose(fp);
//计算
strcpy(strInfo, " CPU USER% SYS% WAIT% IDLE%\n");
for (i=0; i
{
printf("buf=%s",buf[i]);
printf("bufNext=%s",bufNext[i]);
sscanf(buf[i],"%s%ld%ld%ld%ld%ld%ld%d",name,&user,&nice,&sys,&idle,&iowait,&irq,&softirq);
sscanf(bufNext[i],"%s%ld%ld%ld%ld%ld%ld%d",name,&userNext,&niceNext,&sysNext,&idleNext,&iowaitNext,&irqNext,&softirqNext);
cpu_total =
(userNext+niceNext+sysNext+idleNext+iowaitNext+irqNext+softirqNext)
- (user+nice+sys+idle+iowait+irq+softirq);
cpu_user = userNext -
user;
cpu_sys = sysNext - sys;
cpu_wait = iowaitNext -
iowait;
cpu_idle = idleNext -
idle;
if (0 == i)
{
fCpuRate =
1.0*(cpu_total-cpu_idle) / cpu_total;
printf("\n%f\n",fCpuRate );
}
if(cpu_total >
0)
{
sprintf(sInfo,"%
5.5s% 5.1f% 5.1f% 5.1f%
5.1f\n",name,cpu_user*100.0/cpu_total,cpu_sys*100.0/cpu_total,cpu_wait*100.0/cpu_total,cpu_idle*100.0/cpu_total);
}
else
{
sprintf(sInfo,"%
5.5s% 5.1f% 5.1f% 5.1f% 5.1f\n",name,0,0,0,100);
}
strcat(strInfo,sInfo);
}
printf("%s\n",strInfo);
return 0;
}
int main()
{
SysCpu();
return 0;
}
--------------------mem------------------------------------------------
#include 
#include 
#include 
#include 
int SysMem()
{
const int MAX_LEN=1024;
char sInfo[MAX_LEN];
char strInfo[1024];
//
long mem_used = -1;
long mem_free = -1;
long mem_total = -1;
char name[20];
float fMemRate;
FILE *fp;
char buf1[128];
char buf2[128];
int i = 0;
memset(sInfo, 0x00, sizeof(sInfo));
memset(strInfo, 0x00, sizeof(strInfo));
//读取文件中mem信息
fp = fopen("/proc/meminfo","r");
if(fp == NULL)
{
perror("fopen:");
return -1;
}
fgets(buf1,sizeof(buf1),fp);
fgets(buf2,sizeof(buf2),fp);
fclose(fp);
//计算
strcpy(strInfo,"
RTOL(kb) FREE(kb) RINUSE(kb) RATE%%\n\n");
sscanf(buf1,"%s%ld",name,&mem_total);
sscanf(buf2,"%s%ld",name,&mem_free);
mem_used = mem_total - mem_free;
fMemRate = 1.0 * mem_used / mem_total;
sprintf(sInfo,"%
6ld %6ld %6ld %6.1f\n",mem_total,mem_free,mem_used,fMemRate);
strcat(strInfo,sInfo);
printf("%s\n",strInfo);
return 0;
}
int main()
{
SysMem();
return 0;
}