linux 获取 CPU 使用信息
2015-10-11 11:20
453 查看
在 Shell 脚本中,我们可以通过 top -n 1 来获取,获取内容如下:
具体参数的意思在这里不做解释,我们主要看一下用 C 代码如何获取 CPU 的使用信息,达到命令 top 的目的。
先来了解一下内核维护的一个借口 /proc/stat 这个文件,使用命令 cat /proc/stat 得到内容如下:
cpu 一行从左到右参数的意思依次是(单位:jiffies):
jiffies 是内核中的一个全局变量,用来记录自系统启动以来产生的节拍数,在 linux 中,一个节拍数大致可以理解为操作系统进程调度的最小时间片,不同 linux 内核可能值有不同,通常在 1ms 到 10ms 之间。
user(103769):从系统启动开始累积到当前时刻,处于用户态的运行时间,不包含 nice 值为负进程的运行时间。
nice(0):从系统启动开始累计到当前时刻,nice 值为负的进程所占用的 CPU 时间。
system(164913):从系统启动开始累计到当前时刻,处于内核态的运行时间。
idle(1503325):从系统启动开始累计到当前时刻,除 IO 等待时间以外的其它等待时间。
iowait(0):从启动启动开始累计到当前时刻,IO 等待时间。(版本 2.5.41 后)
irq(0):从系统启动开始累计到当前时刻,硬中断时间。(版本 2.6.0 后)
softirq(15396):从系统启动开始累计到当前时刻,软中断时间。(版本 2.6.0 后)
stealstolen(0):which is the time spent in other operating systems when running in a virtualized environment.
guest (0):which is the time spent running a virtual CPU for guest operating systems under the control of the Linux kernel.(版本 2.6.24 后)
总体运行时间:TotalCPUTime = user + nice + idle + iowait + irq + softirq + stealstolen + guest。
CPU 运行时间:UserCPUTime = TotalCPUTime - idle - iowait
C 代码实现:
扩展:
一、获取进程使用 CPU 率,/proc/<pid>/stat 文件
该文件包含了某一进程所有的活动的信息,该文件中的所有值都是从系统启动开始累计到当前时刻。以下通
过实例数据来说明该文件中各个字段的含义。下面我们来看一下4081这个进程的详细信息:
从左到右各列的具体信息如下:
pid=4081
进程号
comm=atd
应用程序或者命令的名字
task_state=S
任务状态,R:running;S:sleeping;D:dist sleep;T:stop;T:tracing stop;Z:zombie;X:dead
ppid=1
父进程 ID
pgid=4081
线程组号
sid=4081
该进程所在的会话组 ID
tty_nr=0
该任务的tty终端的设备号,
tty_pgrp=-1
终端的进程组号,当前运行在该任务所在终端的前台任务
task->flags=4194624
进程标志位,查看该任务的特性
min_fit=93
该任务不需要从硬盘拷数据而发生的缺页(次缺页)的次数
cmin_fit=0
累计的改任务的所有的waited-fon进程曾经发生的次缺页的次数目
maj_fit=0
该任务需要从硬盘拷数据而发生的缺页(主缺页)的此数目
cmaj_fit=0
累计的该任务的所有的 waited-fon 进程曾经发生的主缺页的此数目
utime=0
该任务在用户态运行的时间,单位为 jiffies
stime=0
该任务在内核态运行的时间,单位为 jiffies
cutime=0
累计的该任务的所有的 waited-fon 进程曾经在用户态运行的时间,单位为 jiffies
cstime=0
累计的该任务的所有的 waited-fon 进程曾近在内核态运行的时间,单位为 jiffies
priority=18
任务的动态优先级
nice=0
任务的静态优先级
num_threads=1
该任务所在的线程组里的线程的个数
it_real_value=0
由于计算时间间隔导致的下一个 SIGALRM 发送进程的时延,以 jiffies 为单位
start_time=4449
该任务的启动时间大小,单位为 jiffies
vsize=2318336
该任务的虚拟地址空间大小
rss=111
该任务当前驻留物理地址空间的大小
rlim=4294967295
该任务驻留物理地址空间的最大值,单位为 bytes
start_code=3461120
该任务在虚拟地址空间的代码段的起始地址
end_code=3479704
该任务在虚拟地址空间的代码段的结束地址
start_stack=3215230176
该任务在虚拟地址空间栈的结束地址
kstkesp=3215229372
esp
(32 位堆栈指针) 的当前值, 与在进程的内核堆栈页得到的一致.
kstkeip=5280784
指向将要执行的指令的指针, EIP(32 位指令指针)的当前值.
pendingsig=0
待处理信号的位图,记录发送给进程的普通信号
block_sig=0
阻塞信号的位图
sigign=0
忽略的信号的位图
sigcatch=819
23 被俘获的信号的位图
wchan=0
如果该进程是睡眠状态,该值给出调度的调用点
nswap=0
被swapped的页数,当前没用
cnswap=0
所有子进程被swapped的页数的和,当前没用
exit_signal=17
该进程结束时,向父进程所发送的信号
task_cpu(task)=0
运行在哪个CPU上
task_rt_priority=0
实时进程的相对优先级别
task_policy=0
进程的调度策略,0=非实时进程,1=FIFO实时进程;2=RR实时进程
进程的总Cpu时间processCpuTime
= utime + stime + cutime + cstime,该值包括其所有线程的cpu时间
总的 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使用情况求和,得到s
c) s2
- s1得到这个时间间隔内的所有时间片,即totalCpuTime = j2 - j1
;
3、计算空闲时间idle
idle对应第四列的数据,用第二次的第四列 - 第一次的第四列即可
idle=第二次的第四列 - 第一次的第四列
4、计算cpu使用率
pcpu =100* (total-idle)/total
某一进程 CPU 的使用率
计算方法:
1、 采样两个足够短的时间间隔的cpu快照与进程快照,
a) 每一个cpu快照均为(user、nice、system、idle、iowait、irq、softirq、stealstolen、guest)的9元组
b)
每一个进程快照均为 (utime、stime、cutime、cstime)的4元组;
2、分别根据结论2、结论3计算出两个时刻的总的cpu时间与进程的cpu时间,分别
作:totalCpuTime1、totalCpuTime2、processCpuTime1、processCpuTime2
3、计算该进程的cpu使用率
pcpu
= 100*( processCpuTime2 – processCpuTime1) / (totalCpuTime2 – totalCpuTime1)
(按100%计算,如果是多核情况下还需乘以cpu的个数)
参考博客:http://www.blogjava.net/fjzag/articles/317773.html
具体参数的意思在这里不做解释,我们主要看一下用 C 代码如何获取 CPU 的使用信息,达到命令 top 的目的。
先来了解一下内核维护的一个借口 /proc/stat 这个文件,使用命令 cat /proc/stat 得到内容如下:
cpu 一行从左到右参数的意思依次是(单位:jiffies):
jiffies 是内核中的一个全局变量,用来记录自系统启动以来产生的节拍数,在 linux 中,一个节拍数大致可以理解为操作系统进程调度的最小时间片,不同 linux 内核可能值有不同,通常在 1ms 到 10ms 之间。
user(103769):从系统启动开始累积到当前时刻,处于用户态的运行时间,不包含 nice 值为负进程的运行时间。
nice(0):从系统启动开始累计到当前时刻,nice 值为负的进程所占用的 CPU 时间。
system(164913):从系统启动开始累计到当前时刻,处于内核态的运行时间。
idle(1503325):从系统启动开始累计到当前时刻,除 IO 等待时间以外的其它等待时间。
iowait(0):从启动启动开始累计到当前时刻,IO 等待时间。(版本 2.5.41 后)
irq(0):从系统启动开始累计到当前时刻,硬中断时间。(版本 2.6.0 后)
softirq(15396):从系统启动开始累计到当前时刻,软中断时间。(版本 2.6.0 后)
stealstolen(0):which is the time spent in other operating systems when running in a virtualized environment.
guest (0):which is the time spent running a virtual CPU for guest operating systems under the control of the Linux kernel.(版本 2.6.24 后)
总体运行时间:TotalCPUTime = user + nice + idle + iowait + irq + softirq + stealstolen + guest。
CPU 运行时间:UserCPUTime = TotalCPUTime - idle - iowait
C 代码实现:
// CPU 信息结构体typedef struct cpu { unsigned long long USR; unsigned long long NIC; unsigned long long SYS; unsigned long long IDLE; unsigned long long IOWAIT; unsigned long long IRQ; unsigned long long SOFTIRQ; unsigned long long STEAL; unsigned long long TOTAL; unsigned long long USAGE; double BOGOMIPS; }CPU_INFO; // 读取 CPU 信息static inline int readCpuInfo(CPU_INFO *cpu){ if ( NULL == cpu ) { write_log("The parameter is NULL."); return -1; } const char fmt[] = "cpu %llu %llu %llu %llu %llu %llu %llu %llu"; char line[LINE_LEN]; bzero(line, LINE_LEN); FILE *stat = OPEN_FILE("/proc/stat", "r"); if (!fgets(line, LINE_LEN, stat) || line[0] != 'c' ) { close(stat); write_log("Read CPU infonation failed."); return -1; } close(stat); int ret = sscanf(line, fmt, cpu->USR, cpu->NIC, cpu->SYS, cpu->IDLE, cpu->IOWAIT, cpu->IRQ, cpu->SOFTIRQ, cpu->STEAL); if (ret >= 4) { cpu->TOTAL = cpu->USR + cpu->NIC + cpu->SYS + cpu->IDLE + cpu->IOWAIT + cpu->IRQ + cpu->SOFTIRQ + cpu->STEAL; cpu->USAGE = cpu->TOTAL - cpu->IDLE - cpu->IOWAIT; } return ret; } // 通过 CPU 使用时间计算 CPU 的使用率 int getCpuUsageRates() { double usage = 0; CPU_INFO pre_cpu; if ( 4 > readCpuInfo(&pre_cpu) ) { write_log("Get CPU info failed."); return -1; } usleep(100000); CPU_INFO cur_cpu; if ( 4 > readCpuInfo(&cur_cpu) ) { write_log("Get CPU info failed."); return -1; } usage = (cur_cpu.USAGE - pre_cpu.USAGE)/(cur_cpu.TOTAL - pre_cpu.TOTAL) * 100; return usage; }
扩展:
一、获取进程使用 CPU 率,/proc/<pid>/stat 文件
该文件包含了某一进程所有的活动的信息,该文件中的所有值都是从系统启动开始累计到当前时刻。以下通
过实例数据来说明该文件中各个字段的含义。下面我们来看一下4081这个进程的详细信息:
从左到右各列的具体信息如下:
pid=4081
进程号
comm=atd
应用程序或者命令的名字
task_state=S
任务状态,R:running;S:sleeping;D:dist sleep;T:stop;T:tracing stop;Z:zombie;X:dead
ppid=1
父进程 ID
pgid=4081
线程组号
sid=4081
该进程所在的会话组 ID
tty_nr=0
该任务的tty终端的设备号,
tty_pgrp=-1
终端的进程组号,当前运行在该任务所在终端的前台任务
task->flags=4194624
进程标志位,查看该任务的特性
min_fit=93
该任务不需要从硬盘拷数据而发生的缺页(次缺页)的次数
cmin_fit=0
累计的改任务的所有的waited-fon进程曾经发生的次缺页的次数目
maj_fit=0
该任务需要从硬盘拷数据而发生的缺页(主缺页)的此数目
cmaj_fit=0
累计的该任务的所有的 waited-fon 进程曾经发生的主缺页的此数目
utime=0
该任务在用户态运行的时间,单位为 jiffies
stime=0
该任务在内核态运行的时间,单位为 jiffies
cutime=0
累计的该任务的所有的 waited-fon 进程曾经在用户态运行的时间,单位为 jiffies
cstime=0
累计的该任务的所有的 waited-fon 进程曾近在内核态运行的时间,单位为 jiffies
priority=18
任务的动态优先级
nice=0
任务的静态优先级
num_threads=1
该任务所在的线程组里的线程的个数
it_real_value=0
由于计算时间间隔导致的下一个 SIGALRM 发送进程的时延,以 jiffies 为单位
start_time=4449
该任务的启动时间大小,单位为 jiffies
vsize=2318336
该任务的虚拟地址空间大小
rss=111
该任务当前驻留物理地址空间的大小
rlim=4294967295
该任务驻留物理地址空间的最大值,单位为 bytes
start_code=3461120
该任务在虚拟地址空间的代码段的起始地址
end_code=3479704
该任务在虚拟地址空间的代码段的结束地址
start_stack=3215230176
该任务在虚拟地址空间栈的结束地址
kstkesp=3215229372
esp
(32 位堆栈指针) 的当前值, 与在进程的内核堆栈页得到的一致.
kstkeip=5280784
指向将要执行的指令的指针, EIP(32 位指令指针)的当前值.
pendingsig=0
待处理信号的位图,记录发送给进程的普通信号
block_sig=0
阻塞信号的位图
sigign=0
忽略的信号的位图
sigcatch=819
23 被俘获的信号的位图
wchan=0
如果该进程是睡眠状态,该值给出调度的调用点
nswap=0
被swapped的页数,当前没用
cnswap=0
所有子进程被swapped的页数的和,当前没用
exit_signal=17
该进程结束时,向父进程所发送的信号
task_cpu(task)=0
运行在哪个CPU上
task_rt_priority=0
实时进程的相对优先级别
task_policy=0
进程的调度策略,0=非实时进程,1=FIFO实时进程;2=RR实时进程
进程的总Cpu时间processCpuTime
= utime + stime + cutime + cstime,该值包括其所有线程的cpu时间
总的 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使用情况求和,得到s
c) s2
- s1得到这个时间间隔内的所有时间片,即totalCpuTime = j2 - j1
;
3、计算空闲时间idle
idle对应第四列的数据,用第二次的第四列 - 第一次的第四列即可
idle=第二次的第四列 - 第一次的第四列
4、计算cpu使用率
pcpu =100* (total-idle)/total
某一进程 CPU 的使用率
计算方法:
1、 采样两个足够短的时间间隔的cpu快照与进程快照,
a) 每一个cpu快照均为(user、nice、system、idle、iowait、irq、softirq、stealstolen、guest)的9元组
b)
每一个进程快照均为 (utime、stime、cutime、cstime)的4元组;
2、分别根据结论2、结论3计算出两个时刻的总的cpu时间与进程的cpu时间,分别
作:totalCpuTime1、totalCpuTime2、processCpuTime1、processCpuTime2
3、计算该进程的cpu使用率
pcpu
= 100*( processCpuTime2 – processCpuTime1) / (totalCpuTime2 – totalCpuTime1)
(按100%计算,如果是多核情况下还需乘以cpu的个数)
参考博客:http://www.blogjava.net/fjzag/articles/317773.html
相关文章推荐
- Linux(centos7) 源码安装cmake
- linux0.11 块设备驱动与高速缓冲区
- 图解Linux命令之--chown命令
- CentOS7上安装MySQL Workbench
- 图解Linux命令之--alias命令
- 中文名文件上传到linux服务器上以后文件名会乱码(openoffice)
- Linux 硬中断和软中断
- 学习日志---Linux打卡6
- 11个令人吃惊的linux命令
- SecureCRT连接Linux,Vim颜色显示问题 4步搞定
- linux配置matconvnet(GPU support)
- centos linux 系统日常管理4 scp,rsync,md5sum,sha1sum,strace ,find Rsync 常见错误及解决方法 第十七节课
- Linux初步学习(文件权限的三个命令)
- JDK环境变量配置(linux)
- Linux集群-负载均衡lvs-dr实现mysql
- linux 串口工具的安装
- 虚拟机安装麒麟3.2时报unkown filesystem,you need to load the linux kernel first
- linux系统下sd卡的备份与恢复
- linux常用命令总结
- linux(centos)下非root用户执行管理命令