Chinaunix首页 | 论坛 | 博客
  • 博客访问: 20841
  • 博文数量: 2
  • 博客积分: 70
  • 博客等级: 民兵
  • 技术积分: 25
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-09 12:40
文章分类
文章存档

2012年(2)

我的朋友

分类: LINUX

2012-06-25 14:08:40


src:http://www.ibm.com/developerworks/cn/aix/library/0909_unixcpu_wangwh/index.html

因为 Linux 系统特有的开放性,用户可以自主的添加,定义或者改变系统原有的功能。有很多开源项目提供了基于图形的或者命令行的工具,帮助用户更加方便的识别、监控甚至改变系统中的处理器的运行状态。考虑到通用的原则,本文仅介绍常见 Linux 发行版本中已经集成的接口或者工具。

查看 /proc/stat 文件获得 CPU 状态

/proc/stat 的内容包含了系统中的各项基本信息,例如 CPU 状态。用户可以详细了解系统中每个处理器自系统启动以来的运行状态,并以此分析和评估应用环境的工作是否正常。



# cat /proc/stat cpu 507853 325 148706 190270813 190032 152 884 0 0 cpu0 178463 111 68890 95035802 93558 34 96 0 0 cpu1 329389 213 79816 95235010 96474 117 787 0 0 intr 93566218 3310 2 0 0 2 0 3 0 30 0 0 0 4 0 1623929 10015567 2440 20098 0 0 0 0 0 0 0 3712917 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 … … 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 202868862 btime 1242974927 processes 356350 procs_running 1 procs_blocked 0

命令输出的最初几行包含了系统中所有 CPU 的活动信息,在 kernel2.6.29 下的 /proc/stat 中,每行内容的处理器名后有九个数字,而早期的 kernel 会缺失一些内容,比如与虚拟化相关的信息。所有这些数值都是从系统启动开始累计到当前时刻的,并以 0.01 秒为单位。以下是这些数值的解释

  • user: 用户模式占用的 CPU 时间
  • nice: 低优先级用户模式所占用的 CPU 时间
  • system: 系统核心态占用的 CPU 时间
  • idle:cpu 空闲时间
  • iowait:硬盘 IO 等待时间 ( 从 kernel 2.5.41 开始添加此项信息 )
  • irq:硬中断时间 ( 丛 kernel 2.6.0-test4 开始添加此项信息 )
  • softirq:软中断时间(同上)
  • steal:在虚拟环境下,处理其他作业系统占用的 cpu 时间(丛 kernel 2.6.11 开始添加此项信息)
  • guest: 作业系统运行虚拟 cpu 占用 cpu 的时间(丛 kernel2.6.24 开始添加此项信息)

根据 /proc/stat 文件的内容,用户可以自行计算任意时间段内 CPU 的占用率;

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

选取两个时间点 T1 和 T2, CPU 在 T1 和 T2 时间段中的使用时间可以如下计算:

Total=(user2+system2+nice2+idle2+iowait2+irq2+softirq2+steal2+guest2)-( user1+system1+nice1+idle1+iowait1+irq1+softirq1+steal1+guest1)

CPU 空闲百分比:

idle = (idle2 - idle1) / Total * 100%

CPU 占用百分比:

occupy = (1 - idle) * 100%

除了最初的 CPU 行以外,/proc/stat 文件还有其他与系统性能相关的一些参数。其中 ctxt 是系统启动以来 CPU 发生的上下文交换的次数。

读取 /proc/loadavg 文件获得 CPU 状态


# cat /proc/loadavg 5.86 5.78 5.89 12/840 22261

命令输出前三项分别表示最近 1 分钟,最近 5 分钟及最近 15 分钟运行队列中的平均进程数,第四项包括由斜线隔开的两个数值,前者表示当前正由内核调度的进程和线程的数目,后者表示系统当前存活的进程数目;第五个值表示此文件被查看前,最近一个由内核创建的进程的 PID。

利用 ps 命令

系统处理器的工作是处理任务。而在现代操作系统中,任务是以进程的形式表现的。所以定位分析系统处理器的问题,也需要用到进程相关的接口或指令。ps 命令是分析 CPU 状态的重要工具,它读取 /proc 文件系统中各进程的信息,并且加以显示。用户首先需要定位感兴趣的进程,这可以通过 ps 命令来确定,也可以结合其他系统工具。很多情况下,用户仅需关注某个或某几个进程。



[root@bldlnx02 ~]# ps -e -o pcpu,pid,user,sgi_p,cmd |grep -v PID| sort -k 1| tail -5 0.0 8 root * [khelper] 0.0 9 root * [kacpid] 0.1 21949 root * sshd: csm@pts/0 0.2 21951 root * -bash 99.9 12392 root * /usr/bin/Xvnc -inetd -query 127.0.0.1 -once -depth 24 -desktop VNC Session Manager -rfbauth /root/.vnc/passwd -geometry 640x480

系统中通常会有多进程的程序运行。当这些进程占用了较多的 CPU 时间时,可以单独列出该程序的所有进程。多数情况下,用户也需要进程的启动时间,状态,父进程号 (PPID),占用的内存来分析系统和进程的状态。



# ps -C nfsd -o cmd,pCPU,start_time,user,ppid,size,stat CMD %CPU START USER PPID SZ STAT [nfsd] 0.0 May12 root 1 0 D [nfsd] 0.0 May12 root 1 0 D [nfsd] 0.0 May12 root 1 0 D [nfsd] 0.0 May12 root 1 0 D [nfsd] 0.0 May12 root 1 0 S [nfsd] 0.0 May12 root 1 0 S [nfsd] 0.0 May12 root 1 0 D [nfsd] 0.0 May12 root 1 0 D

在以上输出中各个字段分别表示如下含义:

  • CMD 进程命令名
  • %CPU 进程占用的 CPU 百分比
  • START 进程启动的时间
  • USER 进程的属主
  • PPID 父进程号
  • SZ 进程占用的内存空间
  • STAT 进程状态

ps 命令的输出结果表示系统中共有八个 nfs 服务进程,是根用户在一天以前启动的。当前这些进程没有使用 CPU 时间或内存。并且分别处于不同的状态。ps 命令可以接受的状态种类共有七种,仅介绍清单 15 中的两个作为示例

  • D 无法中断的休眠状态(通常 IO 的进程)
  • S 处于休眠状态

可以看到有六个 nfs 服务进程处于无法中断的休眠状态,这表示 NFS 服务出现了问题。用户可以通过检查物理存储可用性,查看 /var/log/messages 文件或 sysrq-T 系统 trace 等手段来进一步定位和排查错误。

本段的最后给出一段例子代码,可以获得一段时间内的 CPU 利用率,并且找出系统中占用 CPU 较多的进程,已在 Redhat 企业服务器和 Suse 企业服务器上测试通过。代码首先选取两个相隔一分钟的两个时间段,分别读取文件 /proc/stat 的内容,获得 CPU 在两个时刻的进程占用时间等数值来计算 CPU 利用率。并且读取文件 /proc/loadavg 获得处理器上的集成负载。在负载较高的情况下,调用命令 ps 找出消耗 CPU 最多的几个进程,及其所在的处理器(processor)。



# 两次读取 /proc/stat 文件的内容 my $file = '/proc/stat'; open FILE, "<$file" or die "Failed to open file $file.\n"; my @fir_contents = ; close FILE; sleep 60; open FILE, "<$file" or die "Failed to open file $file.\n"; my @sec_contents = ; close FILE; # 把 /proc/stat 文件的内容存入一个散列 my (%cpuinfo); my $cpu_num = 0; my $line_num = 0; foreach my $line (@fir_contents, @sec_contents){ $line_num ++; if ($line =~ m/^cpu/) { # 判断当前数据来自第一次读取还是第二次读取 my $info_time; if ($line_num <= scalar(@fir_contents)) { $info_time = "first"; }else { $info_time = "second"; } # 向散列写入数据 chomp $line; my ($cpu, $user, $nice, $sys, $idle, $io, $irq, $softirq, $steal, $guest) = split /\s+/, $line; $cpuinfo{$info_time}{$cpu}{'user'} = $user; $cpuinfo{$info_time}{$cpu}{'nice'} = $nice; $cpuinfo{$info_time}{$cpu}{'sys'} = $sys; $cpuinfo{$info_time}{$cpu}{'idle'} = $idle; $cpuinfo{$info_time}{$cpu}{'io'} = $io; $cpuinfo{$info_time}{$cpu}{'irq'} = $irq; $cpuinfo{$info_time}{$cpu}{'softirq'} = $softirq; $cpuinfo{$info_time}{$cpu}{'$steal'} = $steal; $cpuinfo{$info_time}{$cpu}{'guest'} = $guest; $cpu_num ++; } } # 读取散列中的数据以计算 CPU 利用率 my (%cpu_data, %cpu_usage); foreach my $info_time (keys %cpuinfo) { foreach my $cpu (keys %{$cpuinfo{$info_time}}) { $cpu_data{$cpu}{$info_time}{'total'} = 0; $cpu_data{$cpu}{$info_time}{'idle'} = $cpuinfo{$info_time}{$cpu}{'idle'}; foreach my $key (keys %{$cpuinfo{$info_time}{$cpu}}) { $cpu_data{$cpu}{$info_time}{'total'} += $cpuinfo{$info_time}{$cpu}{$key}; } } } my $check_proc; foreach my $cpu (keys %cpu_data){ my $idle_interval = $cpu_data{$cpu}{'second'}{'idle'} - $cpu_data{$cpu}{'fisrt'}{'idle'}; my $total_interval = $cpu_data{$cpu}{'second'}{'total'} - $cpu_data{$cpu}{'fisrt'}{'total'}; $cpu_usage{$cpu} = (1 - $idle_interval/$total_interval); if ($cpu_usage{$cpu} > 0.5) {$check_proc = 1;} } # 从 /proc/loadavg 读取处理器上的进程负载 $file = '/proc/loadavg'; open FILE, "<$file" or die "Failed to open file $file.\n"; my @contents = ; close FILE; my ($load1, $load5, $load15, $proc_num, $pid); foreach my $line (@contents) {($load1, $load5, $load15, $proc_num, $pid) = \n split /\s+/, $line;} if ($load1 > 5) {$check_proc = 1;} # 如果处理器空闲,退出 if (!$check_proc){ print "CPU load on this machine is normal.\n"; exit 0; } # 如果处理器繁忙,找出占用 CPU 时间的进程 my @output = `ps -e -o pcpu,pid,user,sgi_p,cmd |grep -v PID| sort -k 1| tail -10`; foreach my $line (@output){ $line =~ s/^\s+//g; my ($cpu, $pid, $user, $proc, $cmd) = split /\s+/, $line; if ($cpu < 5) {next;} # 输出进程号和进程占用的 CPU 百分比 print "Process $pid of user $user takes $cpu% CPU time on processor $proc.\n"; } exit 0;
阅读(2719) | 评论(0) | 转发(0) |
0

上一篇:nohz下的timer机制和进程调度

下一篇:没有了

给主人留下些什么吧!~~