linux cpu计算
- 格式:doc
- 大小:90.00 KB
- 文档页数:12
Linux下的CPU利用率计算原理详解我们在搞性能测试的时候,对后台服务器的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的利用率(详细的解释可参考:/System/procstat.htm)。
这个文件包含了所有CPU活动的信息,该文件中的所有值都是从系统启动开始累计到当前时刻。
如:1.[sailorhzr@builder ~]$ cat /proc/stat2.cpu 432661 13295 86656 422145968 171474 233 53463.cpu0 123075 2462 23494 105543694 16586 0 46154.cpu1 111917 4124 23858 105503820 69697 123 3715.cpu2 103164 3554 21530 105521167 64032 106 3346.cpu3 94504 3153 17772 105577285 21158 4 247.intr 1065711094 1057275779 92 0 6 6 0 4 0 3527 0 0 0 70 0 20 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7376958 0 0 0 0 0 0 0 1054602 0 0 0 0 0 00 30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 08.ctxt 190678879.btime 113918753110.processes 27001411.procs_running 112.procs_blocked 013.输出解释CPU 以及CPU0、CPU1、CPU2、CPU3每行的每个参数意思(以第一行为例)为:CPU时间=user+system+nice+idle+iowait+irq+softirq“intr”这行给出中断的信息,第一个为自系统启动以来,发生的所有的中断的次数;然后每个数对应一个特定的中断自系统启动以来所发生的次数。
linux cpu使用率计算方法Linux操作系统中,CPU使用率是一个重要的性能指标,它可以帮助我们了解系统的负载情况,判断系统的运行状态是否正常。
那么,如何计算Linux系统中的CPU使用率呢?CPU使用率的计算方法可以分为两个部分:采样和计算。
采样是指获取CPU使用情况的数据,计算是指将采样的数据进行处理,得出CPU使用率的结果。
下面我们分别介绍一下采样和计算的具体方法。
1. 采样方法Linux系统中,可以通过多种方式采样CPU使用情况的数据。
常用的方法有以下几种:(1)/proc/stat文件/proc/stat是一个虚拟的文件系统,它提供了各种系统信息的统计数据。
其中,CPU使用情况的数据可以从第一行的“cpu”行中获取。
具体来说,/proc/stat文件中“cpu”行的各个字段含义如下: user:用户态CPU时间,不包括nice值为负的进程nice:nice值为负的进程所占用的CPU时间system:内核态CPU时间idle:空闲CPU时间iowait:IO等待时间irq:硬中断时间softirq:软中断时间steal:虚拟机偷取的CPU时间guest:虚拟机运行的CPU时间guest_nice:nice值为负的虚拟机运行的CPU时间(2)top命令top命令可以实时显示系统的进程和CPU使用情况。
在top命令输出的信息中,CPU使用率可以从第三行中的“%CPU”字段中获取。
(3)sar命令sar命令可以采样系统各项资源的使用情况,包括CPU使用率。
具体命令如下:sar -u 1 10表示每秒采样一次,共采样10次。
2. 计算方法一旦获取了CPU使用情况的数据,就可以进行计算了。
计算方法如下:(1)计算总的CPU使用时间可以通过/proc/stat文件中“cpu”行中的user、nice、system、idle、iowait、irq、softirq、steal、guest和guest_nice字段,计算出从系统启动开始到现在的总CPU使用时间。
Linux系统查看物理CPU个数、核数、逻辑CPU个数查看物理CPU个数、核数、逻辑CPU个数总核数 = 物理CPU个数 X 每颗物理CPU的核数总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数# 查看物理CPU个数这个服务器有2个物理CPU[root@salt ~]# cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l2# 查看每个物理CPU中core的个数(核数)[root@salt ~]# cat /proc/cpuinfo| grep "cpu cores"| uniqcpu cores : 8# 查看逻辑CPU的个数[root@salt ~]# cat /proc/cpuinfo| grep "processor"| wc -l32这个服务器⼀共32个逻辑CPU,也就是我们常说的线程数,也就说每个核可以提供2个线程。
# 查看CPU信息(型号)[root@salt ~]# cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c32 Intel(R) Xeon(R) CPU E5-2620 v4 @ 2.10GHzlscpu命令查看cpu的详细信息[root@salt ~]# lscpuArchitecture: x86_64 #指CPU的架构CPU op-mode(s): 32-bit, 64-bitByte Order: Little EndianCPU(s): 32 #指CPU的核数On-line CPU(s) list: 0-31Thread(s) per core: 2 #指的每个 Core 的硬件线程数,超线程,数值为1,表⽰不⽀持超线程Core(s) per socket: 8 #指的是CPU的核⼼(单个CPU的核⼼)Socket(s): 2 #指的是主板上CPU的插槽,服务器通常会有多个NUMA node(s): 2Vendor ID: GenuineIntelCPU family: 6Model: 79Model name: Intel(R) Xeon(R) CPU E5-2620 v4 @ 2.10GHz #cpu型号Stepping: 1CPU MHz: 2100.046BogoMIPS: 4199.39Virtualization: VT-xL1d cache: 32KL1i cache: 32KL2 cache: 256KL3 cache: 20480KNUMA node0 CPU(s): 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30NUMA node1 CPU(s): 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31。
想获取一下目标机运行时linux系统的硬件占用情况,写了这几个小程序,以后直接用了。
方法就是读取proc下的文件来获取了。
cpu使用率:/proc/stat ,内存使用情况:/proc/meminfo看程序:/**************************************************************** @file: statusinfo.c** @brief: 从linux系统获取cpu及内存使用情况** @version 1.0** @author 抹黑** @date 2009年3月17日****************************************************************/typedef struct PACKED //定义一个cpu occupy的结构体{char name[20]; //定义一个char类型的数组名name有20个元素unsigned int user; //定义一个无符号的int类型的userunsigned int nice; //定义一个无符号的int类型的niceunsigned int system;//定义一个无符号的int类型的systemunsigned 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函数含有一个形参结构体类弄的指针OFILE *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);//第一次(用户+优先级+系统+空闲)的时间再赋给odnd = (unsigned long) (n->user + n->nice + n->system +n->idle);//第二次(用户+优先级+系统+空闲)的时间再赋给odid = (unsigned long) (n->user - o->user); //用户第一次和第二次的时间之差再赋给id sd = (unsigned long) (n->system - o->system);//系统第一次和第二次的时间之差再赋给if((nd-od) != 0)cpu_use = (int)((sd+id)*10000)/(nd-od); //((用户+系统)乖100)除(第一次和第二次的时间差)再赋给g_cpu_usedelse 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下如何获取cpu的利用率"proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。
linux top命令cpu总占用率计算在Linux中,使用top命令查看系统状态时,可以看到每个进程的CPU占用率。
要计算CPU总占用率,可以使用以下方法:1. 使用top命令:当你在Linux上打开终端并输入top命令时,你将看到一个动态更新的屏幕,其中显示了系统中各个进程的资源占用情况。
在顶部,你会看到一个标题栏,其中包含各种系统统计信息,如“Tasks”(任务)、“Cpu(s)”(CPU)、“Mem”(内存)和“Swap”(交换空间)。
要查看CPU总占用率,请关注标题栏中与“Cpu(s)”相关的列。
该列会显示如下信息:us:用户空间占用的CPU百分比。
sy:系统空间占用的CPU百分比。
ni:更改过优先级的进程占用的CPU百分比。
id:空闲的CPU百分比。
wa:等待I/O操作的CPU百分比。
hi:处理硬件中断的CPU百分比。
si:处理软件中断的CPU百分比。
st:虚拟化环境中被偷走的CPU时间百分比。
要计算CPU总占用率,你需要将“us”和“sy”列的值相加。
例如,如果“us”是40%,而“sy”是30%,那么CPU总占用率就是70%。
2. 注意:这只是显示在top命令输出中的所有进程的总计值,它并不是系统作为一个整体的CPU使用率。
如果有大量用户空间和系统空间的进程同时运行,总计值可能会很高。
“us”和“sy”列表示的是进程级的CPU占用率,而实际的系统级CPU占用率可能受到其他因素的影响,如内核线程、I/O等待等。
3. 其他工具:除了top命令之外,还有许多其他工具可以帮助你监视和管理Linux系统上的性能,如htop、glances等。
这些工具可能提供更多关于CPU和其他资源使用情况的详细信息。
请注意,这些工具和命令可能需要root权限才能完全访问系统信息。
linux top 计算进程cpu 使用率的原理
Linux中的top命令用于显示系统的实时性能信息,包括CPU的使用率。
top命令计算进程CPU使用率的原理主要基于两个指标:累计运行时间和累计用户时间。
top命令每隔一定时间(默认1秒)更新一次进程的CPU使用情况。
在更新时,top命令会计算每个进程的累计运行时间和累计用户时间。
累计运行时间表示进程自启动以来所经过的时间,而累计用户时间表示进程在CPU上执行的时间。
CPU使用率的计算公式如下:
CPU使用率= 累计用户时间/ 累计运行时间* 100%
需要注意的是,top命令显示的CPU使用率可能超过100%。
这是因为在多核CPU环境下,一个进程可以同时使用多个CPU核心,因此它的CPU使用率可能会超过100%。
在这种情况下,CPU使用率超过100%表示该进程在所有核心上的总运行时间超过了系统总运行时间。
此外,在top命令中,CPU使用率是根据上次更新以来的时间来计算的。
因此,在短时间内,进程的CPU使用率可能会出现较大的波动。
总之,Linux top命令计算进程CPU使用率的原理是根据进程的累计用户时间和累计运行时间来计算的,用以反映进程在CPU上的使用情况。
Linux下内存使用率、CPU使用率、以及运行原理Linux下怎样查看机器配置啊?cpu/内存/硬盘dmesg显示开机信息。
kernel会将开机信息存储在ring buffer中。
您若是开机时来不及查看信息,可利用dmesg来查看。
开机信息亦保存在/var/log目录中,名称为dmesg的文件里dmesg|grep hd硬盘dmesg|grep cpucpudmesg|grep proc内存dmesg|grep redhat操作系统dmesg|more更多信息uname -a操作系统版本查看linux cpu和内存利用率在系统维护的过程中,随时可能有需要查看 CPU 使用率,并根据相应信息分析系统状况的需要。
在 CentOS 中,可以通过 top 命令来查看 CPU 使用状况。
运行 top 命令后,CPU 使用状态会以全屏的方式显示,并且会处在对话的模式-- 用基于 top 的命令,可以控制显示方式等等。
退出 top 的命令为 q (在 top 运行中敲 q 键一次)。
操作实例:在命令行中输入“top”即可启动 toptop 的全屏对话模式可分为3部分:系统信息栏、命令输入栏、进程列表栏。
第一部分 -- 最上部的系统信息栏:第一行(top):“00:11:04”为系统当前时刻;“3:35”为系统启动后到现在的运作时间;“2 users”为当前登录到系统的用户,更确切的说是登录到用户的终端数 -- 同一个用户同一时间对系统多个终端的连接将被视为多个用户连接到系统,这里的用户数也将表现为终端的数目;“load average”为当前系统负载的平均值,后面的三个值分别为1分钟前、5分钟前、15分钟前进程的平均数,一般的可以认为这个数值超过 CPU 数目时,CPU 将比较吃力的负载当前系统所包含的进程;第二行(Tasks):“59 total”为当前系统进程总数;“1 running”为当前运行中的进程数;“58 sleeping”为当前处于等待状态中的进程数;“0 stoped”为被停止的系统进程数;“0 zombie”为被复原的进程数;第三行(Cpus):分别表示了 CPU 当前的使用率;第四行(Mem):分别表示了内存总量、当前使用量、空闲内存量、以及缓冲使用中的内存量;第五行(Swap):表示类别同第四行(Mem),但此处反映着交换分区(Swap)的使用情况。
linux下查看机器是cpu是⼏核的⼏个cpumore /proc/cpuinfo |grep "physical id"|uniq|wc -l每个cpu是⼏核(假设cpu配置相同)more /proc/cpuinfo |grep "physical id"|grep "0"|wc -lcat /proc/cpuinfo | grep processor1. 查看物理CPU的个数#cat /proc/cpuinfo |grep "physical id"|sort |uniq|wc -l2. 查看逻辑CPU的个数#cat /proc/cpuinfo |grep "processor"|wc -l3. 查看CPU是⼏核#cat /proc/cpuinfo |grep "cores"|uniq4. 查看CPU的主频#cat /proc/cpuinfo |grep MHz|uniq# uname -aLinux euis1 2.6.9-55.ELsmp #1 SMP Fri Apr 20 17:03:35 EDT 2007 i686 i686 i386 GNU/Linux(查看当前操作系统内核信息)# cat /etc/issue | grep LinuxRed Hat Enterprise Linux AS release 4 (Nahant Update 5)(查看当前操作系统发⾏版信息)# cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c8 Intel(R) Xeon(R) CPU E5410 @ 2.33GHz(看到有8个逻辑CPU, 也知道了CPU型号)# cat /proc/cpuinfo | grep physical | uniq -c4 physical id : 04 physical id : 1(说明实际上是两颗4核的CPU)# getconf LONG_BIT32(说明当前CPU运⾏在32bit模式下, 但不代表CPU不⽀持64bit)# cat /proc/cpuinfo | grep flags | grep ' lm ' | wc -l8(结果⼤于0, 说明⽀持64bit计算. lm指long mode, ⽀持lm则是64bit)如何获得CPU的详细信息:linux命令:cat /proc/cpuinfo⽤命令判断⼏个物理CPU,⼏个核等:逻辑CPU个数:# cat /proc/cpuinfo | grep "processor" | wc -l物理CPU个数:# cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l每个物理CPU中Core的个数:# cat /proc/cpuinfo | grep "cpu cores" | wc -l是否为超线程?如果有两个逻辑CPU具有相同的”core id”,那么超线程是打开的。
Linux调度器负载计算方法一、引言Linux调度器是操作系统中负责任务调度的核心组件,它负责分配CPU时间给各个进程,以实现多任务处理。
在Linux中,调度器的负载计算方法对于任务调度至关重要,因为它决定了哪些进程应该获得CPU时间以及它们的优先级。
本文将深入探讨Linux调度器的负载计算方法,特别是CPU使用率和负载平均值这两个关键指标。
二、CPU使用率CPU使用率是指进程在单位时间内占用的CPU时间百分比。
它是衡量进程对CPU资源需求的重要指标。
在Linux调度器中,CPU使用率用于确定进程的优先级。
通常,高CPU使用率的进程会获得更高的优先级,因为它们对CPU资源的渴求更大。
CPU使用率的计算公式为:CPU使用率 = (进程的CPU时间 / 观察时间) * 100%其中,进程的CPU时间是指在观察时间内,进程实际占用的CPU时间。
观察时间通常设定为一个固定的时间段,例如1秒或5秒。
三、负载平均值负载平均值是Linux调度器中另一个重要的负载计算方法。
它反映了系统负载的平均水平,包括用户进程、系统进程和空闲进程的数量。
负载平均值的计算公式为:负载平均值 = (当前正在运行的进程数 + 已提交的进程数) / 可用CPU个数其中,已提交的进程数是那些已经提交但尚未运行的进程数量。
可用CPU 个数是指系统中当前可用的物理或逻辑CPU核心数。
负载平均值可以帮助调度器了解系统的整体负载情况,从而做出更合理的任务调度决策。
在Linux中,可以使用uptime命令查看系统的负载平均值。
四、总结与展望Linux调度器的负载计算方法是实现高效任务调度的关键。
通过关注CPU 使用率和负载平均值这两个指标,调度器能够更好地了解进程的资源需求和系统负载状况。
未来,随着技术的发展和应用的演变,调度器可能会面临更多的挑战和需求。
例如,随着云计算和虚拟化技术的普及,调度器需要处理更加复杂的资源分配和任务调度问题。
因此,进一步研究和优化Linux调度器的负载计算方法,提高其性能和适应性,对于推动操作系统技术的发展具有重要意义。
Linux CPU利用率计算原理及内核实现Jun042011Leave a Comment Written by chen我们经常使用top命令来查看CPU利用率,如root@ubuntu:~# toptop – 09:16:29 up 6 min, 4 users, load average: 0.01, 0.22, 0.17Tasks: 149 total, 1 running, 147 sleeping, 0 stopped, 1 zombieCpu(s): 2.8%us, 6.7%sy, 0.2%ni, 89.9%id, 0.3%wa, 0.0%hi, 0.1%si, 0.0%st Mem: 508000k total, 404092k used, 103908k free, 47764k buffersSwap: 522236k total, 0k used, 522236k free, 184992k cachedPID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND1 root 20 0 3040 1812 1252 S 0.0 0.4 0:01.81 init2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd3 root 20 0 0 0 0 S 0.0 0.0 0:00.06 ksoftirqd/05 root 20 0 0 0 0 S 0.0 0.0 0:00.56 kworker/u:06 root RT 0 0 0 0 S 0.0 0.0 0:00.00 migration/0Linux系统中计算CPU利用率是通过读取/proc/stat文件数据而计算得来。
CPU 利用率计算方法如下:root@ubuntu:~# cat /proc/statcpu 711 56 2092 7010 104 0 20 0 0 0cpu0 711 56 2092 7010 104 0 20 0 0 0intr 31161 94 64 0 1 75 0 3 0 0 0 0 0 1423 0 0 382 2825 4798 0 226 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0ctxt 101085btime 1307117390processes 2078procs_running 1procs_blocked 0softirq 32534 0 7796 151 143 4225 0 81 0 12 20126root@ubuntu:~#第一行cpu为总的信息,cpu0… cpu n为各个具体CPU信息cpu 711 56 2092 7010 104 0 20 0 0 0上面共有10个值(单位:jiffies),前面8个值分别为:User time,711 Nice time,56System time,2092 Idle time,7010Waiting time,104 Hard Irq time,0SoftIRQ time,20 Steal time,0CPU时间=user+system+nice+idle+iowait+irq+softirq+Stl%us=(User time + Nice time)/CPU时间*100%%sy=(System time + Hard Irq time +SoftIRQ time)/CPU时间*100%%id=(Idle time)/CPU时间*100%%ni=(Nice time)/CPU时间*100%%wa=(Waiting time)/CPU时间*100%%hi=(Hard Irq time)/CPU时间*100%%si=(SoftIRQ time)/CPU时间*100%%st=(Steal time)/CPU时间*100%我们根据/proc/stat文件来分析Linux内核统计数据实现方式。
内核实现下面以内核源码版本2.6.32-71.29.1.el6 x86_64为例,来介绍内核源码实现。
/proc/stat文件的创建由函数proc_stat_init()实现,在文件fs/proc/stat.c中,在内核初始化时调用。
./proc/stat文件相关函数时间均在stat.c文件中。
对/proc/stat文件的读写方法为proc_stat_operations。
00160: static const struct file_operations proc_stat_operations = { 00161: .open = stat_open,00162: .read = seq_read,00163: .llseek = seq_lseek,00164: .release = single_release,00165: };打开文件函数stat_open(),函数首先申请大小为size的内存,来存放临时数据(也是我们看到的stat里的最终数据)。
00136: static int stat_open(struct inode *inode, struct file *file) 00137: {00138: unsigned size = 4096 * (1 + num_possible_cpus() / 32); 00139: char *buf;00140: struct seq_file *m;00141: int res;00142:00143: / * don’t ask for more than the kmalloc() max size, currently 128 KB */00144: if (size > 128 * 1024)00145: size = 128 * 1024;00146: buf = kmalloc(size, GFP_KERNEL);00147: if (! buf)00148: return - ENOMEM;00149:00150: res = single_open(file, show_stat, NULL);00151: if (! res) {00152: m = file- >private_data;00153: m- >buf = buf;00154: m- >size = size;00155: } else00156: kfree(buf);00157: return res;00158: } ? end stat_open ?00159:/proc/stat文件的数据由show_stat()函数填充。
注意43行for_each_possible_cpu(i)循环,是计算所有CPU的数据,如我们前面的示例看到的/proc/stat文件中第一行cpu值。
00025: static int show_stat(struct seq_file *p, void *v)00026: {00027: int i, j;00028: unsigned long jif;00029: cputime64_t user, nice, system, idle, iowait, irq, softirq, steal; 00030: cputime64_t guest;00031: u64 sum = 0;00032: u64 sum_softirq = 0;00033: unsigned int per_softirq_sums[NR_SOFTIRQS] = {0}; 00034: struct timespec boottime;00035: unsigned int per_irq_sum;00036:00037: user = nice = system = idle = iowait =00038: irq = softirq = steal = cputime64_zero;00039: guest = cputime64_zero;00040: getboottime(&boottime);00041: jif = _sec;00042:00043: for_each_possible_cpu(i) {00044: user = cputime64_add(user, kstat_cpu(i)er); 00045: nice = cputime64_add(nice, kstat_cpu(i).cpustat.nice);00046: system = cputime64_add(system,kstat_cpu(i).cpustat.system);00047: idle = cputime64_add(idle, kstat_cpu(i).cpustat.idle); 00048: idle = cputime64_add(idle, arch_idle_time(i));00049: iowait = cputime64_add(iowait, kstat_cpu(i).cpustat.iowait); 00050: irq = cputime64_add(irq, kstat_cpu(i).cpustat.irq);00051: softirq = cputime64_add(softirq,kstat_cpu(i).cpustat.softirq);00052: steal = cputime64_add(steal, kstat_cpu(i).cpustat.steal);00053: guest = cputime64_add(guest, kstat_cpu(i).cpustat.guest); 00054: for_each_irq_nr(j) {00055: sum += kstat_irqs_cpu(j, i);00056: }计算总的CPU各个值user、nice、system、idle、iowait、irq、softirq、steal后,就分别计算各个CPU的使用情况(78~103行)。