linux系统下CPU利用率的计算

目录

一、设计思路

二、参考代码


一、设计思路

        思路很简单:主要通过解析 /proc/stat 文件中记录的 CPU 使用详情信息。内容如下:

$ cat /proc/stat
cpu  500 0 1148 37091 0 21 0 0 0 0
cpu0 46 0 193 4603 0 17 0 0 0 0
cpu1 17 0 34 4792 0 0 0 0 0 0
cpu2 198 0 171 4473 0 3 0 0 0 0
cpu3 21 0 20 4801 0 0 0 0 0 0
cpu4 96 0 331 4415 0 0 0 0 0 0
cpu5 34 0 82 4726 0 0 0 0 0 0
cpu6 62 0 128 4653 0 0 0 0 0 0
cpu7 26 0 189 4628 0 1 0 0 0 0
intr 894498 377553 332 0 0 0 0 0 0 0 287178 0 0 1078 0 8572 189 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 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 494453
btime 1658673908
processes 21
procs_running 1
procs_blocked 0
softirq 531871 0 166655 5588 285920 8660 0 272 0 791 63985

        该文件的第一行记录了 CPU 时间片的分布情况。字段依次为:

user 

从系统启动开始累计到当前时刻,用户态的CPU时间,不包含nice值为负进程。

nice 

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

system 

从系统启动开始累计到当前时刻,核心时间

idle 

从系统启动开始累计到当前时刻,除IO等待时间以外其它等待时间

iowait 

从系统启动开始累计到当前时刻,IO等待时间

irq 

从系统启动开始累计到当前时刻,硬中断时间

softirq 

从系统启动开始累计到当前时刻,软中断时间

    CPU利用率 = 1 - (CPU空闲时间片 / CPU时间片总和)。

    CPU时间片总和 = user + nice + system + idle + iowait + irq + softirq

    CPU 空闲时间片 = idle

         需要注意的是,/proc/stat 文件中记录的时间都是自系统启动开始的累计时间,所以计算CPU的使用率需要依据一个时间间隔内的CPU时间片分布情况。

二、参考代码

        只是参考,肯定跑不起来的,缺了一些头文件。

typedef struct cpu_info_
{
    long time_user;
    long time_nice;
    long time_system;
    long time_idle;
    long time_iowait;
    long time_irq;
    long time_sirq;
}cpu_info;

cpu_info *cpu_info_snap()
{
    char cmd[CMD_LEN_GER] = "cat /proc/stat", cpu_info_tmp[CMD_LEN_RES] = "", str_tmp[10] = "";
    FILE *file = popen(cmd, "r");
    if (file == NULL)
    {
        LOG_FATAL("[CPU]-->cmd(%s) execute failed\n", cmd);
        return NULL;
    }
    cpu_info *cpu_time = (cpu_info *)malloc(sizeof(cpu_info));
    fgets(cpu_info_tmp, CMD_LEN_RES, file);
    sscanf(cpu_info_tmp, "%s %ld %ld %ld %ld %ld %ld %ld", str_tmp, &cpu_time->time_user, &cpu_time->time_nice, &cpu_time->time_system, 
                        &cpu_time->time_idle, &cpu_time->time_iowait, &cpu_time->time_irq, &cpu_time->time_sirq);
    return cpu_time;
}

long cpu_time_total(cpu_info *info)
{
    if (info == NULL)
    {
        return ERROR;
    }
    return info->time_user + info->time_nice + info->time_system + info->time_idle + info->time_iowait + info->time_irq + info->time_sirq;
}

int cpu_gen_info(char *cpu_info_str, int len, char *err)
{
    cpu_info *cpu_time_pre = cpu_info_snap();
    usleep(100*1000);
    cpu_info *cpu_time_back = cpu_info_snap();

    long ct_total_pre = cpu_time_total(cpu_time_pre), ct_total_back = cpu_time_total(cpu_time_back);
    if (ct_total_pre < 0 || ct_total_back < 0 || ct_total_pre >= ct_total_back)
    {
        LOG_ERROR("[CPU]->cpu time format error! pre(%ld)--back(%ld)\n", ct_total_pre, ct_total_back);
        return ERROR;
    }

    long ct_idle_pre = cpu_time_pre->time_idle, ct_idle_back = cpu_time_back->time_idle;
    if(ct_idle_back <= ct_idle_pre)
    {
        LOG_ERROR("[CPU]->cpu idle time fotmat errot! pre(%ld)--back(%ld)\n", ct_idle_pre, ct_idle_back);
        return ERROR;
    }

    int rate = (1 - (ct_idle_back * 1.0 - ct_idle_pre * 1.0) / (ct_total_back * 1.0 - ct_total_pre * 1.0)) * 100;
    printf("%d \n", rate);

    free(cpu_time_pre);
    free(cpu_time_back);
    return OK;
}

        有什么不足欢迎提出来。

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
Linux 系统计算进程 CPU 利用率的公式如下: CPU 利用率 = 100 * (进程使用的 CPU 时间 / 系统CPU 时间) 其中,进程使用的 CPU 时间指的是进程在 CPU 上运行的时间,包括用户态和内核态的时间。系统CPU 时间指的是系统中所有 CPU 的累计时间。 以下是用 C 语言实现该公式的代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define BUF_SIZE 1024 int main(int argc, char* argv[]) { if (argc != 2) { fprintf(stderr, "Usage: %s <pid>\n", argv[0]); exit(EXIT_FAILURE); } char stat_file[BUF_SIZE]; snprintf(stat_file, BUF_SIZE, "/proc/%s/stat", argv[1]); FILE* fp = fopen(stat_file, "r"); if (!fp) { perror("fopen"); exit(EXIT_FAILURE); } unsigned long utime, stime, cutime, cstime; fscanf(fp, "%*d %*s %*c %*d %*d %*d %*d %*d %*u " "%*u %*u %*u %*u %lu %lu %lu %lu", &utime, &stime, &cutime, &cstime); fclose(fp); unsigned long long total_time = utime + stime + cutime + cstime; unsigned long long system_uptime = 0; fp = fopen("/proc/uptime", "r"); if (fp) { fscanf(fp, "%llu", &system_uptime); fclose(fp); } unsigned long long cpu_time = sysconf(_SC_CLK_TCK) * system_uptime; double cpu_usage = 100.0 * total_time / cpu_time; printf("CPU usage: %.2f%%\n", cpu_usage); return 0; } ``` 该程序的输入参数为进程 PID,它会读取 `/proc/PID/stat` 文件中的 CPU 时间信息,并根据系统启动时间计算系统CPU 时间,最终输出进程的 CPU 利用率
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我要出家当道士

打赏是不可能,这辈子都不可能

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值