linux平台jiffies和HZ Cpu使用率

HZ:1秒钟内,时钟中断的次数,即1秒钟内,系统时钟的节拍次数。

jiffies:全局变量,用来记录系统自启动以来产生的节拍总数

系统运行时间(以秒为单位):system_time=(jiffies)/HZ。

eg:jiffies定时器,HZ=1000,精度只能达到1ms。,HZ=100,精度只能达到10ms,
        jiffies+msecs_to_jiffies(xx ms);   可做到ms级,

Linux中的软定时器(低分辨率的timer_list定时器)利用CPU时钟中断来感知时间更新,并通过TIMER_SOFTIRQ软中断来运行到期的定时器。时钟中断每秒触发HZ次,HZ的值可在编译时通过CONFIG_HZ选项来配置。 
较高的HZ可使系统具有更好的交互性和相应速度,适合于桌面系统等交互性强的系统,但HZ增高也会导致内核中处理定时中断以及调用定时器例程更频繁,使系统开销也随之增高。

proc文件系统

/proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为内核与进程提供通信的接口。用户和应用程序可以通过/proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息,如进程,是动态改变的,所以用户或应用程序读取/proc目录中的文件时,proc文件系统是动态从系统内核读出所需信息并提交的。

/proc目录中有一些以数字命名的目录,它们是进程目录。系统中当前运行的每一个进程在/proc下都对应一个以进程号为目录名的目录/proc/pid,它们是读取进程信息的接口。此外,在Linux 2.6.0-test6以上的版本中/proc/pid目录中有一个task目录,/proc/pid/task目录中也有一些以该进程所拥有的线程的线程号命名的目录/proc/pid/task/tid,它们是读取线程信息的接口。

/proc/cpuinfo文件

该文件中存放了有关 cpu的相关信息(型号,缓存大小等)。

processor (0)                       cpu的一个物理标识

结论1:可以通过该文件根据processor出现的次数统计cpu的逻辑个数(包括多核、超线程)

/proc/stat文件

该文件包含了所有CPU活动的信息,该文件中的所有值都是从系统启动开始累计到当前时刻。不同内核版本中该文件的格式可能不大一致,

第一行的数值表示的是CPU总的使用情况,所以我们只要用第一行的数字计算就可以了。下表解析第一行各数值的含义:

参数          解析(单位:jiffies)

(jiffies是内核中的一个全局变量,用来记录自系统启动一来产生的节拍数,在linux中,一个节拍大致可理解为操作系统进程调度的最小时间片,不同linux内核可能值有不同,通常在1ms到10ms之间)

user (38082)    从系统启动开始累计到当前时刻,处于用户态的运行时间,不包含 nice值为负进程。

nice (627)      从系统启动开始累计到当前时刻,nice值为负的进程所占用的CPU时间

system (27594)  从系统启动开始累计到当前时刻,处于核心态的运行时间

idle (893908)   从系统启动开始累计到当前时刻,除IO等待时间以外的其它等待时间iowait (12256从系统启动开始累计到当前时刻,IO等待时间(since 2.5.41)

irq (581)           从系统启动开始累计到当前时刻,硬中断时间(since 2.6.0-test4)

softirq (895)      从系统启动开始累计到当前时刻,软中断时间(since 2.6.0-test4)stealstolen(0)                   which is the time spent in other operating systems when running in a virtualized environment(since 2.6.11)

guest(0)                               which is the time spent running a virtual  CPU  for  guest operating systems under the control of the Linux kernel(since 2.6.24)

 

结论2:总的cpu时间totalCpuTime = user + nice + system + idle + iowait + irq + softirq + stealstolen  +  guest

/proc/<pid>/stat文件

该文件包含了某一进程所有的活动的信息,该文件中的所有值都是从系统启动开始累计到当前时刻。以下通过实例数据来说明该文件中各字段的含义。

说明:以下只解释对我们计算Cpu使用率有用相关参数

参数                                                                解释

pid=6873                            进程号

utime=1587                       该任务在用户态运行的时间,单位为jiffies

stime=41958                      该任务在核心态运行的时间,单位为jiffies

cutime=0                            所有已死线程在用户态运行的时间,单位为jiffies

cstime=0                            所有已死在核心态运行的时间,单位为jiffies

结论3进程的总Cpu时间processCpuTime = utime + stime + cutime + cstime,该值包括其所有线程的cpu时间。

/proc/<pid>/task/<tid>/stat文件

该文件包含了某一进程所有的活动的信息,该文件中的所有值都是从系统启动开始累计到当前时刻。该文件的内容格式以及各字段的含义同/proc/<pid>/stat文件。

         注意,该文件中的tid字段表示的不再是进程号,而是linux中的轻量级进程(lwp),即我们通常所说的线程。

 

结论4:线程Cpu时间threadCpuTime = utime + stime

ps 命令

结论5ps命令算出来的cpu使用率相对于进程启动时的平均值,随着进程运行时间的增大,该值会趋向于平缓。

top命令

通过top命令可以查看系统中相关进程的实时信息(cpu使用率等)。

结论7在多核的情况下top命令输出的cpu使用率实质是按cpu个数*100%计算的。

单核情况下Cpu使用率的计算

基本思想

通过读取/proc/stat 、/proc/<pid>/stat、/proc/<pid>/task/<tid>/stat以及/proc/cpuinfo这几个文件获取总的Cpu时间、进程的Cpu时间、线程的Cpu时间以及Cpu的个数的信息,然后通过一定的算法进行计算(采样两个足够短的时间间隔的Cpu快照与进程快照来计算进程的Cpu使用率)。

总的Cpu使用率计算

计算方法:

1、  采样两个足够短的时间间隔的Cpu快照,分别记作t1,t2,其中t1、t2的结构均为:

(user、nice、system、idle、iowait、irq、softirq、stealstolen、guest)的9元组;

2、  计算总的Cpu时间片totalCpuTime

a)         把第一次的所有cpu使用情况求和,得到s1;

b)         把第二次的所有cpu使用情况求和,得到s2;

c)         s2 - s1得到这个时间间隔内的所有时间片,即totalCpuTime = j2 - j1 ;

3、计算空闲时间idle

idle对应第四列的数据,用第二次的第四列 - 第一次的第四列即可

idle=第二次的第四列 - 第一次的第四列

6、计算cpu使用率

pcpu =100* (total-idle)/total

某一进程Cpu使用率的计算

计算方法:  

1.采样两个足够短的时间间隔的cpu快照与进程快照,

a)         每一个cpu快照均为(user、nice、system、idle、iowait、irq、softirq、stealstolen、guest)的9元组;

b)         每一个进程快照均为 (utimestimecutimecstime)4元组;

2.               分别根据结论2、结论3计算出两个时刻的总的cpu时间与进程的cpu时间,分别记作:totalCpuTime1totalCpuTime2processCpuTime1processCpuTime2

total_cpu_slice_1=`cat /proc/stat|grep "cpu "|awk '{for(i=2;i<=NF;i++)j+=$i;print j;}'`

total_process_slice_1=`cat /proc/${pid}/stat|awk '{print $14+$15+$16+$17}'`

3.               计算该进程的cpu使用率pcpu = 100*( processCpuTime2 – processCpuTime1) / (totalCpuTime2 – totalCpuTime1) (按100%计算,如果是多核情况下还需乘以cpu的个数);

cpu_usage=`echo "scale=2; 100 * ($total_process_slice_2 - $total_process_slice_1) / ($total_cpu_slice_2 - $total_cpu_slice_1)" |bc`

 

某一线程Cpu使用率的计算

计算方法:  

1.               采样两个足够短的时间隔的cpu快照与线程快照,

a)         每一个cpu快照均为(user、nice、system、idle、iowait、irq、softirq、stealstealon、guest)的9元组;

b)         每一个线程快照均为 (utimestime)2元组;

2.               分别根据结论2、结论4计算出两个时刻的总的cpu时间与线程的cpu时间,分别记作:totalCpuTime1totalCpuTime2threadCpuTime1threadCpuTime2

3.               计算该线程的cpu使用率pcpu = 100*( threadCpuTime2 – threadCpuTime1) / (totalCpuTime2 – totalCpuTime1) (按100%计算,如果是多核情况下还需乘以cpu的个数);

 

/proc/<pid>/stat 参数说明

参数 解释
Name 应用程序或命令的名字
State 任务的状态,运行/睡眠/僵死/
SleepAVG 任务的平均等待时间(以nanosecond为单位),交互式任务因为休眠次数多、时间长,它们的 sleep_avg
也会相应地更大一些,所以计算出来的优先级也会相应高一些。
Tgid 线程组号
Pid 任务ID
Ppid 父进程ID
TracerPid 接收跟踪该进程信息的进程的ID号
Uid Uid euid suid fsuid
Gid Gid egid sgid fsgid
FDSize 文件描述符的最大个数,file->fds
Groups
VmSize(KB) 任务虚拟地址空间的大小
(total_vm-reserved_vm),其中total_vm为进程的地址空间的大小,reserved_vm:进程在预留或特殊的内存间的物理页
VmLck(KB) 任务已经锁住的物理内存的大小。锁住的物理内存不能交换到硬盘 (locked_vm)
VmRSS(KB) 应用程序正在使用的物理内存的大小,就是用ps命令的参数rss的值 (rss)
VmData(KB) 程序数据段的大小(所占虚拟内存的大小),存放初始化了的数据;
(total_vm-shared_vm-stack_vm)
VmStk(KB) 任务在用户态的栈的大小 (stack_vm)
VmExe(KB) 程序所拥有的可执行虚拟内存的大小,代码段,不包括任务使用的库 (end_code-start_code)
VmLib(KB) 被映像到任务的虚拟内存空间的库的大小 (exec_lib)
VmPTE 该进程的所有页表的大小,单位:kb
Threads 共享使用该信号描述符的任务的个数,在POSIX多线程序应用程序中,线程组中的所有线程使用同一个信号描述符。
SigQ 待处理信号的个数
SigPnd 屏蔽位,存储了该线程的待处理信号
ShdPnd 屏蔽位,存储了该线程组的待处理信号
SigBlk 存放被阻塞的信号
SigIgn 存放被忽略的信号
SigCgt 存放被俘获到的信号
CapInh Inheritable,能被当前进程执行的程序的继承的能力
CapPrm
Permitted,进程能够使用的能力,可以包含CapEff中没有的能力,这些能力是被进程自己临时放弃的,CapEff是CapPrm的一个子集,进程放弃没有必要的能力有利于提高安全性
CapEff Effective,进程的有效能力

 

转载于:https://my.oschina.net/u/347414/blog/1924400

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用Linux系统提供的Proc文件系统来实现获取CPU使用率的功能。具体步骤如下: 1. 打开/proc/stat文件,该文件记录了系统整体的CPU使用情况以及每个CPU核心的使用情况。 2. 读取文件内容,找到以“cpu”开头的行,该行记录了整个系统的CPU使用情况,以及每个CPU核心的使用情况。 3. 解析行内容,按照空格分隔,获取各个字段的值,其中第1个字段为“cpu”,后面的字段分别对应各个CPU核心的使用情况(如果有多个核心)。 4. 计算CPU使用率,根据CPU使用情况的变化量,计算出CPU使用率。 具体的代码实现可以参考以下示例: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define CPU_NUM 4 // 假设有4个CPU核心 static unsigned long long last_total_jiffies[CPU_NUM] = {0}; static unsigned long long last_work_jiffies[CPU_NUM] = {0}; // 获取CPU使用情况 int get_cpu_usage(double *usage) { FILE *fp; char line[1024]; unsigned long long total_jiffies[CPU_NUM], work_jiffies[CPU_NUM]; int i, j; fp = fopen("/proc/stat", "r"); if (fp == NULL) { printf("Open /proc/stat failed\n"); return -1; } // 读取文件内容 for (i = 0; i < CPU_NUM; i++) { fgets(line, sizeof(line), fp); if (strncmp(line, "cpu", 3) == 0) { char *p = strtok(line, " "); for (j = 0; j < 10; j++) { p = strtok(NULL, " "); if (p == NULL) { printf("Parse /proc/stat failed\n"); fclose(fp); return -1; } if (j == 0) { total_jiffies[i] = atoll(p); } else { work_jiffies[i] += atoll(p); } } } else { printf("Unexpected line in /proc/stat\n"); fclose(fp); return -1; } } fclose(fp); // 计算CPU使用率 for (i = 0; i < CPU_NUM; i++) { if (last_total_jiffies[i] != 0) { unsigned long long total_diff = total_jiffies[i] - last_total_jiffies[i]; unsigned long long work_diff = work_jiffies[i] - last_work_jiffies[i]; double tmp = (double)work_diff / total_diff; usage[i] = tmp * 100; } last_total_jiffies[i] = total_jiffies[i]; last_work_jiffies[i] = work_jiffies[i]; } return 0; } int main() { double usage[CPU_NUM]; while (1) { if (get_cpu_usage(usage) == 0) { for (int i = 0; i < CPU_NUM; i++) { printf("CPU%d usage: %.2f%%\n", i, usage[i]); } } sleep(1); } return 0; } ``` 该程序会每秒钟获取一次CPU使用率,并输出到屏幕上。其中,CPU_NUM为CPU核心数,可以根据实际情况进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值