(一)jiffies
全局变量jiffies记录自系统启动以来产生的节拍数,在系统启动时jiffies初始化为0,每次时钟中断时会增加jiffies的数值。也就是会说,每秒钟jiffies增加的数值就是系统的HZ数。
jiffies的类型为无符号长整型(unsigned long)
进程计算系统占用节拍和用户态占用节拍使用jiffies为单位。进程启动以来占用cpu的用户态和系统态的节拍数在pid/stat文件中表明,top工具就是直接读取/proc/<pid>/stat文件来计算进程的cpu使用百分比的。
(二)proc/<pid>/stat文件详解
pid:进程号(包含轻量级进程,就是线程)
comm:应用程序或者命令的名字
task_stat:R任务的状态,Running/Sleeping(TASK_INTERRUPTIBLE)/Disk sleep(TASK_UNINTERRUPTIBLE)/T/Zombie
ppid:父进程ID
pgid:线程组号
utime:用户态运行时间,单位为jiffies
stime:该进程在系统态运行时间,单位为jiffies
priority:任务的动态优先级
nice:任务的静态优先级
task_cpu:运行在那个cpu上
。。。。。还有很多项
实际上,proc下的stat文件就是内核中下面结构体的proc文件系统输出
typedef struct statstruct_proc {
- int pid; /** The process id. **/
- char exName [_POSIX_PATH_MAX]; /** The filename of the executable **/
- char state; /** 1 **/ /** R is running, S is sleeping,
- D is sleeping in an uninterruptible wait,
- Z is zombie, T is traced or stopped **/
- unsigned euid, /** effective user id **/
- egid; /** effective group id */
- int ppid; /** The pid of the parent. **/
- int pgrp; /** The pgrp of the process. **/
- int session; /** The session id of the process. **/
- int tty; /** The tty the process uses **/
- int tpgid; /** (too long) **/
- unsigned int flags; /** The flags of the process. **/
- unsigned int minflt; /** The number of minor faults **/
- unsigned int cminflt; /** The number of minor faults with childs **/
- unsigned int majflt; /** The number of major faults **/
- unsigned int cmajflt; /** The number of major faults with childs **/
- int utime; /** user mode jiffies **/
- int stime; /** kernel mode jiffies **/
- int cutime; /** user mode jiffies with childs **/
- int cstime; /** kernel mode jiffies with childs **/
- int counter; /** process's next timeslice **/
- int priority; /** the standard nice value, plus fifteen **/
- unsigned int timeout; /** The time in jiffies of the next timeout **/
- unsigned int itrealvalue; /** The time before the next SIGALRM is sent to the process **/
- int starttime; /** 20 **/ /** Time the process started after system boot **/
- unsigned int vsize; /** Virtual memory size **/
- unsigned int rss; /** Resident Set Size **/
- unsigned int rlim; /** Current limit in bytes on the rss **/
- unsigned int startcode; /** The address above which program text can run **/
- unsigned int endcode; /** The address below which program text can run **/
- unsigned int startstack; /** The address of the start of the stack **/
- unsigned int kstkesp; /** The current value of ESP **/
- unsigned int kstkeip; /** The current value of EIP **/
- int signal; /** The bitmap of pending signals **/
- int blocked; /** 30 **/ /** The bitmap of blocked signals **/
- int sigignore; /** The bitmap of ignored signals **/
- int sigcatch; /** The bitmap of catched signals **/
- unsigned int wchan; /** 33 **/ /** (too long) **/
- int sched, /** scheduler **/
- sched_priority; /** scheduler priority **/
- } procinfo;
(三)top工具源码简介
之前的项目中在top工具上增加patch,由于项目中的某些统计信息使用top的值计算进程的占用率,而在top第一次统计是会有不准确的情况。top计算实时cpu利用率的原理是,选取两个采样时间点A和B,A的utime+stime 减去B时间点的utime+stime,再除以AB时间点之间换算100%的总jiffes数。当在top中一直不断在键盘输入时,这样重复的打断会导致AB时间点相隔非常短,只有一个jiffes,除数非常小导致计算出来的cpu占用率大于100%。
我们加上一个patch,使得top内核进程占用率大于100%时,显示100%。