ちょっと詳細なCPUモニタ

/proc/statを読み込んでCPU使用率をモニタリングする@Linux
ちょっと詳細で、userで消費している時間、system、nice、iowait、irq、softirq、steal、guest で別々に数値を取れる。個々の意味はヨクワカラナイ ^^;


実行結果はこんな感じ:

non-idle : 0.710000
user     : 0.410000
system   : 0.255000
nice     : 0.000000
iowait   : 0.000000
irq      : 0.000000
softirq  : 0.045000
steal    : 0.000000
guest    : 0.000000

がんばってネットワーク通信するプログラムを動かしている最中で、user, system, softirqが上がっている。
1秒おきに更新される。


プログラム:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

static int pexit(const char* msg)
{
    perror(msg);
    exit(1);
}

typedef unsigned long long cpu64_t;
struct cpu_t {
    cpu64_t user;
    cpu64_t nice;
    cpu64_t system;
    cpu64_t idle;
    cpu64_t iowait;
    cpu64_t irq;
    cpu64_t softirq;
    cpu64_t steal;
    cpu64_t guest;
};

static void read_stat(struct cpu_t* cpu)
{
    char buf[256];
    int fd = open("/proc/stat", O_RDONLY, 1);
    if(fd < 0) { pexit("open"); }
    if(read(fd, buf, sizeof(buf)) < sizeof(buf)) { pexit("read"); }
    close(fd);

    memset(cpu, 0, sizeof(struct cpu_t));
    sscanf(buf,  "cpu  %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu %Lu",
            &cpu->user, &cpu->nice, &cpu->system, &cpu->idle, &cpu->iowait,
            &cpu->irq, &cpu->softirq, &cpu->steal, &cpu->guest);
}

int main(void)
{
    struct cpu_t before;
    read_stat(&before);

    setvbuf(stdout, NULL, _IONBF, 0);

    while(true) {
        usleep(1*1000*1000);

        struct cpu_t now;
        read_stat(&now);

        cpu64_t total =
            (now.user    - before.user) +
            (now.system  - before.system) +
            (now.nice    - before.nice) +
            (now.idle    - before.idle) +
            (now.iowait  - before.iowait) +
            (now.irq     - before.irq) +
            (now.softirq - before.softirq) +
            (now.steal   - before.steal) +
            (now.guest   - before.guest);

        printf("non-idle : %lf\n", ((double)(total - now.idle + before.idle)) / ((double)total));
        printf("user     : %lf\n", ((double)(now.user    - before.user    ))  / ((double)total));
        printf("system   : %lf\n", ((double)(now.system  - before.system  ))  / ((double)total));
        printf("nice     : %lf\n", ((double)(now.nice    - before.nice    ))  / ((double)total));
        printf("iowait   : %lf\n", ((double)(now.iowait  - before.iowait  ))  / ((double)total));
        printf("irq      : %lf\n", ((double)(now.irq     - before.irq     ))  / ((double)total));
        printf("softirq  : %lf\n", ((double)(now.softirq - before.softirq ))  / ((double)total));
        printf("steal    : %lf\n", ((double)(now.steal   - before.steal   ))  / ((double)total));
        printf("guest    : %lf\n", ((double)(now.guest   - before.guest   ))  / ((double)total));
        printf("\e[9F");

        before = now;
    }
}