Linux系统C语言获取所有CPU核心的利用率“/proc/stat”

源码地址:https://github.com/Rtoax/test/blob/master/c/cpu/cpu_occupy-proc-stat.c


首先看一下文件"/proc/stat"

//"/proc/stat"
//---------------------------------
//      user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice.
//cpu  195044598 6619 410450970 967314001 64039 0 85058 394458 0 0
//cpu0 48705507 1701 102480874 241499274 14130 0 82302 103069 0 0
//cpu1 48866063 1895 102699462 241657644 15853 0 1245 97930 0 0
//cpu2 48782413 1260 102714102 242031473 18001 0 790 96743 0 0
//cpu3 48690614 1762 102556531 242125609 16054 0 720 96715 0 0

上面的数值依次为:user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice.

根据计算公式

(user + nice + system)/(user + nice + system + idle + iowait + irq + softirq)*100%

或者省去一些项

(user + nice + system)/(user + nice + system + idle)*100%

需要注意的是,我们需要统计一段时间的值来计算瞬时CPU利用率。那我们修改公式为:

[(user1 + nice1 + system1) - (user0 + nice0 + system0)]
    /[(user1 + nice1 + system1 + idle1) - (user0 + nice0 + system0 + idle0)]*100%

是不是很简单。下面给出完整的程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define NR_CPU_CORES    sysconf(_SC_NPROCESSORS_ONLN)   //CPU核心总数

struct __cpu_core_stat {        
    //"/proc/stat"
    //---------------------------------
    //      user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice.
    //cpu  195044598 6619 410450970 967314001 64039 0 85058 394458 0 0
    //cpu0 48705507 1701 102480874 241499274 14130 0 82302 103069 0 0
    //cpu1 48866063 1895 102699462 241657644 15853 0 1245 97930 0 0
    //cpu2 48782413 1260 102714102 242031473 18001 0 790 96743 0 0
    //cpu3 48690614 1762 102556531 242125609 16054 0 720 96715 0 0
    long double user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice;
};

struct __cpu_core_stat_pair {
    struct __cpu_core_stat stat[2]; //0-start, 1-end
    struct {
        int integer, decimal;
    }occupy;
//    long double occupy;
};

struct cpu_cores_occupy {
    
    int nr_cpu_core;
    struct __cpu_core_stat_pair *cpus_stat;
    
};

static int cpu_cores_occupy_init(struct cpu_cores_occupy *cco)
{
    if(!cco)
        return -1;

    cco->nr_cpu_core = NR_CPU_CORES;
    cco->cpus_stat = malloc(sizeof(struct __cpu_core_stat_pair)*(NR_CPU_CORES+1));
    return 0;
}

static int __cpu_cores_occupy_get(struct cpu_cores_occupy *cco, int stat_idx/*0-start, 1-end*/)
{
    int icore = 0;
    FILE *fp;
    struct __cpu_core_stat_pair *cpus_stat = cco->cpus_stat;
    
    fp = fopen("/proc/stat","r");

    for(icore=0;icore<=cco->nr_cpu_core;icore++) {
        fscanf(fp,"%*s %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf",
                &cpus_stat[icore].stat[stat_idx].user, 
                &cpus_stat[icore].stat[stat_idx].nice, 
                &cpus_stat[icore].stat[stat_idx].system, 
                &cpus_stat[icore].stat[stat_idx].idle, 
                &cpus_stat[icore].stat[stat_idx].iowait, 
                &cpus_stat[icore].stat[stat_idx].irq, 
                &cpus_stat[icore].stat[stat_idx].softirq, 
                &cpus_stat[icore].stat[stat_idx].steal, 
                &cpus_stat[icore].stat[stat_idx].guest, 
                &cpus_stat[icore].stat[stat_idx].guest_nice);
    }
    fclose(fp);
}

static int cpu_cores_occupy_getstart(struct cpu_cores_occupy *cco)
{
    return __cpu_cores_occupy_get(cco, 0);
}

static int cpu_cores_occupy_getend(struct cpu_cores_occupy *cco)
{
    return __cpu_cores_occupy_get(cco, 1);
}

static int cpu_cores_occupy_call(struct cpu_cores_occupy *cco)
{
    
    int icore = 0, idx;
    
    struct __cpu_core_stat_pair *cpus_stat = cco->cpus_stat;
    
    for(icore=0;icore<=cco->nr_cpu_core;icore++) {
        
        struct __cpu_core_stat *s0 = &cpus_stat[icore].stat[0];
        struct __cpu_core_stat *s1 = &cpus_stat[icore].stat[1];

        long double s0_0 = (s0->user+s0->nice+s0->system);
        long double s1_0 = (s1->user+s1->nice+s1->system);
        
        long double s0_1 = (s0->user+s0->nice+s0->system+s0->idle);
        long double s1_1 = (s1->user+s1->nice+s1->system+s1->idle);
        
        long double occupy = (s1_0 - s0_0) / (s1_1 - s0_1);

        cpus_stat[icore].occupy.integer = (int)(occupy*100);
        cpus_stat[icore].occupy.decimal = (int)(occupy*10000);

//        printf("cpu%d %Lf = (%Lf - %Lf) / (%Lf - %Lf)\n", icore-1, cpus_stat[icore].occupy, s1_0, s0_0, s1_1, s0_1);                            
    }
}


static int cpu_cores_occupy_display(struct cpu_cores_occupy *cco)
{
    int icore = 0;
    
    struct __cpu_core_stat_pair *cpus_stat = cco->cpus_stat;
    
    system("clear");
    for(icore=0;icore<=cco->nr_cpu_core;icore++) {
        printf("cpu%d \t%3d.%-4d %%\n", icore-1,cpus_stat[icore].occupy.integer, cpus_stat[icore].occupy.decimal);
    }

}

int main()
{
    struct cpu_cores_occupy cco;
    
    cpu_cores_occupy_init(&cco);

    for(;;)
    {
        cpu_cores_occupy_getstart(&cco);

        sleep(1);
        
        cpu_cores_occupy_getend(&cco);

        cpu_cores_occupy_call(&cco);

        cpu_cores_occupy_display(&cco);
    }
}

开始运行

[root@localhost cpu]# ./a.out 
cpu-1 	  0.25   %
cpu0 	  0.0    %
cpu1 	  1.101  %
cpu2 	  0.0    %
cpu3 	  0.0    %

我们写一个有自旋锁死锁的程序,或者干脆一个while(1);并绑定核心运行,如下:

[root@localhost c]# taskset -c 1 ./a.out &
[1] 182556
[root@localhost c]# taskset -c 3 ./a.out &
[2] 182569

结果如下:

即可看见CPU利用率100%的情况,然后我们用top指令验证一下:

确认无误,下班。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值