菜鸟笔记
提升您的技术认知

计算cpu利用率-ag真人游戏

一般来说对于需要大量cpu计算的进程,当前端压力越大时,cpu利用率越高。但对于i/o网络密集型的进程,即使请求很多,服务器的cpu也不一定很到,这时的服务瓶颈一般是在磁盘的i/o上。比较常见的就是,大文件频繁读写的cpu开销远小于小文件频繁读写的开销。因为在i/o吞吐量一定时,小文件的读写更加频繁,需要更多的cpu来处理i/o的中断。

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

在linux的内核中,有一个全局变量:jiffies。jiffies代表时间。它的单位随硬件平台的不同而不同。系统里定义了一个常数hz,代表每秒种最小时间间隔的数目,这个值可以在内核编译的时候修改。这样jiffies的单位就是1/hz。intel平台jiffies的单位是1/100秒,这就是系统所能分辨的最小时间间隔了。这里以jiffies为1/100秒为例。每个cpu时间片,jiffies都要加1。cpu的利用率就是用执行用户态 系统态的jiffies除以总的jifffies来表示。

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

[test@pc1 ~]$ cat /proc/stat
cpu 432661 13295 86656 422145968 171474 233 5346
cpu0 123075 2462 23494 105543694 16586 0 4615
cpu1 111917 4124 23858 105503820 69697 123 371
cpu2 103164 3554 21530 105521167 64032 106 334
cpu3 94504 3153 17772 105577285 21158 4 24
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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 0 0 0 1054602 0 0 0 0 0 0 0 30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 19067887
btime 1139187531
processes 270014
procs_running 1
procs_blocked 0

输出解释

cpu以及cpu0、cpu1、cpu2、cpu3每行的每个参数意思(以第一行为例)

参数解释

user (432661) 从系统启动开始累计到当前时刻,用户态的cpu时间(单位:jiffies),不包含nice值为负的进程。
nice (13295) 从系统启动开始累计到当前时刻,nice值为负的进程所占用的cpu时间(单位:jiffies)
system (86656) 从系统启动开始累计到当前时刻,核心时间(单位:jiffies)
idle (422145968) 从系统启动开始累计到当前时刻,除硬盘io等待时间以外其它等待时间(单位:jiffies)
iowait (171474) 从系统启动开始累计到当前时刻,硬盘io等待时间(单位:jiffies)
irq (233) 从系统启动开始累计到当前时刻,硬中断时间(单位:jiffies)
softirq (5346) 从系统启动开始累计到当前时刻,软中断时间(单位: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

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

total_0=user[0] nice[0] system[0] idle[0] iowait[0] irq[0] softirq[0]
total_1=user[1] nice[1] system[1] idle[1] iowait[1] irq[1] softirq[1]
cpu usage=(idle[0]-idle[1]) / (total_0-total_1) * 100

bash实现

#!/bin/sh
## echo user nice system idle iowait irq softirq
cpulog_1=$(cat /proc/stat | grep 'cpu ' | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')
sys_idle_1=$(echo $cpulog_1 | awk '{print $4}')
total_1=$(echo $cpulog_1 | awk '{print $1 $2 $3 $4 $5 $6 $7}')
sleep 1
cpulog_2=$(cat /proc/stat | grep 'cpu ' | awk '{print $2" "$3" "$4" "$5" "$6" "$7" "$8}')
sys_idle_2=$(echo $cpulog_2 | awk '{print $4}')
total_2=$(echo $cpulog_2 | awk '{print $1 $2 $3 $4 $5 $6 $7}')
sys_idle=`expr $sys_idle_2 - $sys_idle_1`
total=`expr $total_2 - $total_1`
sys_usage=`expr $sys_idle/$total*100 |bc -l`
sys_rate=`expr 100-$sys_usage |bc -l`
disp_sys_rate=`expr "scale=3; $sys_rate/1" |bc`
echo $disp_sys_rate%

perl实现

#!/usr/bin/perl
use warnings;
$sleeptime=5;
if (-e "/tmp/stat") {
    unlink "/tmp/stat";
}
open (jiff_tmp, ">>/tmp/stat") || die "can't open /proc/stat file!\n";
open (jiff, "/proc/stat") || die "can't open /proc/stat file!\n";
@jiff_0=;
print jiff_tmp $jiff_0[0] ;
close (jiff);
sleep $sleeptime;
open (jiff, "/proc/stat") || die "can't open /proc/stat file!\n";
@jiff_1=;
print jiff_tmp $jiff_1[0];
close (jiff);
close (jiff_tmp);
@user=`awk '{print \$2}' "/tmp/stat"`;
@nice=`awk '{print \$3}' "/tmp/stat"`;
@system=`awk '{print \$4}' "/tmp/stat"`;
@idle=`awk '{print \$5}' "/tmp/stat"`;
@iowait=`awk '{print \$6}' "/tmp/stat"`;
@irq=`awk '{print \$7}' "/tmp/stat"`;
@softirq=`awk '{print \$8}' "/tmp/stat"`;
$jiff_0=$user[0] $nice[0] $system[0] $idle[0] $iowait[0] $irq[0] $softirq[0];
$jiff_1=$user[1] $nice[1] $system[1] $idle[1] $iowait[1] $irq[1] $softirq[1];
$sys_idle=($idle[0]-$idle[1]) / ($jiff_0-$jiff_1) * 100;
$sys_usage=100 - $sys_idle;
printf ("the cpu usage is %1.2f%%\n",$sys_usage);
网站地图