为什么ps中CPU占用率会有超出%100的现象?
前面的关于ps中的%CPU的含义一文已经介绍了CPU占用率的含义,那么为什么有时会在ps的输出中看到CPU占用率超出%100的现象呢?我们知道在/proc目录下每个进程都会有一个以它的PID以名字的目录,这个目录中有一个stat文件,它包含了和这个进程状态相关的各种信息,它的各个数值对应的含义在内核文档的Documentation/filesystems/proc.txt文件中有明确的定义:
Table 1-3: Contents of the stat files (as of 2.6.22-rc3)
..............................................................................
Field Content
pid process id
tcomm filename of the executable
state state (R is running, S is sleeping, D is sleeping in an
uninterruptible wait, Z is zombie, T is traced or stopped)
ppid process id of the parent process
pgrp pgrp of the process
sid session id
tty_nr tty the process uses
tty_pgrp pgrp of the tty
flags task flags
min_flt number of minor faults
cmin_flt number of minor faults with child's
maj_flt number of major faults
cmaj_flt number of major faults with child's
utime user mode jiffies
stime kernel mode jiffies
cutime user mode jiffies with child's
cstime kernel mode jiffies with child's
priority priority level
nice nice level
num_threads number of threads
start_time time the process started after system boot
vsize virtual memory size
rss resident set memory size
rsslim current limit in bytes on the rss
start_code address above which program text can run
end_code address below which program text can run
start_stack address of the start of the stack
esp current value of ESP
eip current value of EIP
pending bitmap of pending signals (obsolete)
blocked bitmap of blocked signals (obsolete)
sigign bitmap of ignored signals (obsolete)
sigcatch bitmap of catched signals (obsolete)
wchan address where process went to sleep
0 (place holder)
0 (place holder)
exit_signal signal to send to parent thread on exit
task_cpu which CPU the task is scheduled on
rt_priority realtime priority
policy scheduling policy (man sched_setscheduler)
blkio_ticks time spent waiting for block IO
这其中就包括这个进程的stime和utime,而ps就是查看这个文件来获得进程运行的时间,从而计算出%CPU,那么stat这个文件中的stime和utime是怎样得到的呢?在fs/proc/array.c中定义了下面两个函数
int proc_tgid_stat(struct task_struct *task, char *buffer)
{
return do_task_stat(task, buffer, 1);
}
int proc_tid_stat(struct task_struct *task, char *buffer)
{
return do_task_stat(task, buffer, 0);
}
在每次读取进程状态信息时,proc文件系统就是调用这两个函数来填充数据的,它们的区别只有调用do_task_stat时传递的最后一个参数不同,看一下do_task_stat的代码就知道这个参数的含义了:
static int do_task_stat(struct task_struct *task, char *buffer, int whole)
{
...
/* add up live thread stats at the group level */
if (whole) {
struct task_struct *t = task;
do {
min_flt += t->min_flt;
maj_flt += t->maj_flt;
utime = cputime_add(utime, task_utime(t));
stime = cputime_add(stime, task_stime(t));
t = next_thread(t);
} while (t != task);
min_flt += sig->min_flt;
maj_flt += sig->maj_flt;
utime = cputime_add(utime, sig->utime);
stime = cputime_add(stime, sig->stime);
}
...
}
如果whole的值为1, 那么proc文件系统会把这个进程中各个线程的运行时间累加起来,其中next_thread这个函数就是获取这个进程中的下一个线程。在fork的时候,如果指定了CLONE_THREAD标志,也就是新创建的线程和它的父进程在同一个线程组,那么fork会它加入到这个线程中:
if (clone_flags & CLONE_THREAD) {
p->group_leader = current->group_leader;
list_add_tail_rcu(&p->thread_group, &p->group_leader->thread_group);
而next_thread就是没着它的thread_group所在的链表进行遍历,获取线程组中的每个线程。这样就可以解释为什么%CPU字段有超过100%了,因为分子是这个进程(线程组)中所有线程运行的时间,而在同一时刻,同一线程组中的两个不同线程可能在两个不同的CPU上运行,这样总的运行时间就有可能超过物理上真正过去的时间(分母)可见,这种情况只会在SMP的系统上发生。
[root@localhost 3013]# ps aux|grep firefox-bin
root 3091 15.6 26.6 374644 137048 ? Sl 10:05 47:49 /usr/lib/firefox-2.0.0.12/firefox-bin -UILocale zh-CN
[root@localhost 3013]# ps aux -L|grep firefox-bin
root 3091 3091 11.3 12 26.6 374644 137056 ? Sl 10:05 34:40 /usr/lib/firefox-2.0.0.12/firefox-bin -UILocale zh-CN
root 3091 3130 0.0 12 26.6 374644 137056 ? Sl 10:05 0:01 /usr/lib/firefox-2.0.0.12/firefox-bin -UILocale zh-CN
root 3091 3131 0.1 12 26.6 374644 137056 ? Sl 10:05 0:25 /usr/lib/firefox-2.0.0.12/firefox-bin -UILocale zh-CN
root 3091 3140 0.0 12 26.6 374644 137056 ? Sl 10:05 0:00 /usr/lib/firefox-2.0.0.12/firefox-bin -UILocale zh-CN
root 3091 3141 0.0 12 26.6 374644 137056 ? Sl 10:05 0:00 /usr/lib/firefox-2.0.0.12/firefox-bin -UILocale zh-CN
...
上面的L参数面显示其他的线程及其TID,进程号和线程号相同的线程就是它的第一个线程,即3091,进入这个目录可以看到:
[root@localhost proc]# cd 3091
[root@localhost 3091]# ls
attr clear_refs cpuset exe io maps mountstats root smaps status
auxv cmdline cwd fd limits mem oom_adj sched stat task
cgroup coredump_filter environ fdinfo loginuid mounts oom_score schedstat statm wchan
[root@localhost 3091]# cd task/
[root@localhost task]# ls
11850 11851 11853 11854 11855 3091 3130 3131 3140 3141 3142 3155 3158
[root@localhost task]# cd 3130
[root@localhost 3130]# ls
attr clear_refs cwd fd loginuid mounts root smaps status
auxv cmdline environ fdinfo maps oom_adj sched stat wchan
cgroup cpuset exe limits mem oom_score schedstat statm
在一个进程的目录中的task目录下会包含其他的线程的信息。实际上, 在内核中进程和线程并没有什么本质的区别,只不过如果fork的时候共享地址空间那就是线程,否则就是进程。
Email:wudx05@gmail.com
Blog:http://blog.chinaunix.net/u/22326/
阅读(1662) | 评论(2) | 转发(0) |
-->

Aquester2008-04-22 11:06:55
/*
* linux/fs/proc/array.c
*
* Copyright (C) 1992 by Linus Torvalds
* based on ideas by Darren Senn
*
* Fixes:
* Michael. K. Johnson: stat,statm extensions.
*
*
* Pauline Middelink : Made cmdline,envline only break at '\0's, to
* make sure SET_PROCTITLE works. Also removed
* bad '!' which forced address recalculation for
* EVERY character on the current page.

Aquester2008-04-22 11:01:59
From (Eric W. Biederman)
Subject [PATCH 2/4] proc: Rewrite do_task_stat to correctly handle pid namespaces.
Date Mon, 19 Nov 2007 15:06:25 -0700
Currently (as pointed out by Oleg) do_task_stat has a race
when calling task_pid_nr_ns with the task exiting. In addition
do_task_stat is not currently displaying information in the
context of the pid namespace that mounted the /proc filesystem.
So "cut -d' ' -f 1 /proc//stat" may not equal .
This patch fixes the problem by conve
为什么ps中CPU占用率会有超出%100的现象?的更多相关文章
- CPU占用率高分析方法步骤[转载]
由于涉及到私有代码,所有图片都隐去 1.执行TOP命令,确认CPU占用较高的进程PID 根据top命令,发现PID为8691的Java进程占用CPU高达3858%,出现故障 2.确认该进程中CPU占用 ...
- 用Jstack跟踪Cpu占用率的Java线程(转)
以下方法在centOS下执行通过:1.先定位占用cpu高的进程 top 2.使用以下命令 ps p 14766 -L -o pcpu,pid,tid,time,tname,stat,psr | sor ...
- linux上限制用户进程数、cpu占用率、内存使用率
限制进程CPU占用率的问题,给出了一个shell脚本代码如下: renice +10 `ps aux | awk '{ if ($3 > 0.8 && id -u $1 > ...
- linux top命令中各cpu占用率含义
linux top命令中各cpu占用率含义 [尊重原创文章摘自:http://www.iteye.com/topic/1137848]0.3% us 用户空间占用CPU百分比 1.0% sy 内核空间 ...
- (转)linux top命令中各cpu占用率含义及案例分析
原文:https://blog.csdn.net/ydyang1126/article/details/72820349 linux top命令中各cpu占用率含义 0 性能监控介绍 1 确定应用类型 ...
- FL Studio中有关减少CPU占用率的一些技巧
在使用FL Studio20进行音乐制作时经常容易碰到的工程卡顿,声音延迟现象绝大部分是由于电脑CPU超负荷运行而导致的.除了提升电脑本身的性能以外,在FL Studio20中我们也可以运用一些方法来 ...
- Linux下如何查看高CPU占用率线程
转于:http://www.cnblogs.com/lidabo/p/4738113.html 目录(?)[-] proc文件系统 proccpuinfo文件 procstat文件 procpidst ...
- Shell编程检测监控mysql的CPU占用率
shell编程很强大! 网站访问量大的时候mysql的压力就比较大,当mysql的CPU利用率超过300%的时候就不能提供服务了,近乎卡死状态,这时候最好的方法就是重启mysql服务.由于这种事具有不 ...
- 云服务器 ECS Linux 系统 CPU 占用率较高问题排查思路
https://help.aliyun.com/knowledge_detail/41225.html?spm=5176.7841174.2.2.ifP9Sc 注意:本文相关配置及说明已在 CentO ...
随机推荐
- HDU Rightmost Digit
Rightmost Digit Time Limit:1000MS Memory Limit: ...
- 兼容IE8及其他浏览器的回车事件
//阻止默认浏览器行为 function stopDefault(e) { //如果提供了事件对象,则这是一个非IE浏览器 if(e && e.preventDefault) { // ...
- 理解SetCapture()和ReleaseCapture()及GetCapture()作用
正常情况下,鼠标指针位于哪个窗口区域内,鼠标消息就自动发给哪个窗口.如果调用了SetCapture,之后无论鼠标的位置在哪,鼠标消息都发给指定的这个窗口,直到调用ReleaseCapture或者调用S ...
- python中的enumerate()函数用法
enumerate函数用于遍历序列中的元素以及它们的下标,可以非常方便的遍历元素. 比如我在往excel中写数据时就用到了这个函数: data = [] data.append(('预约码', '车牌 ...
- Java 使用itext生成pdf以及下载
使用方法: 1.需要两个jar包: iText-5.0.6.jar //必须使用该版本,否则缺少相关的方法 TextAsian.jar //是为了文档中正常显示中文所必须引用的包 TextAsi ...
- stl_vector.h
stl_vector.h // Filename: stl_vector.h // Comment By: 凝霜 // E-mail: mdl2009@vip.qq.com // Blog: http ...
- bzoj 1069: [SCOI2007]最大土地面积 凸包+旋转卡壳
题目大意: 二维平面有N个点,选择其中的任意四个点使这四个点围成的多边形面积最大 题解: 很容易发现这四个点一定在凸包上 所以我们枚举一条边再旋转卡壳确定另外的两个点即可 旋(xuan2)转(zhua ...
- [SDOI 2017] 序列计数
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=4818 [算法] 考虑容斥 , 用有至少有一个质数的合法序列数 - 没有质数的合法序列 ...
- TYVJ 1094 矩形分割
时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 YHOI Train#4 Problem 1 描述 出于某些方面的需求,我们要把一块N×M的木板切成一个个1× ...
- iOS奇怪的问题,键盘偏移异常
现象描述: 点击UITextView,键盘会弹出.然后点击添加图片,弹出了ActionSheet,键盘自动收缩.接着关闭ActionSheet,发现键盘又弹出了,接着点击Done,想要隐藏键盘,却发现 ...