C Синтаксический анализ / proc / stat для расчета текущей загрузки ЦП для каждого ядра

#c #ubuntu #cpu-usage

#c #ubuntu #загрузка ЦП

Вопрос:

Заранее приношу извинения за свою некомпетентность. Мне это нужно для класса, который я посещаю, но все в C прошло прямо над моей головой, и я изо всех сил пытался удержаться.

Я пытаюсь проанализировать информацию из /proc /stat, чтобы я мог рассчитать «текущее» использование ЦП для каждого ядра и распечатать его. Я собираюсь рассчитать «текущее» использование, вычитая номера более старой версии из более новой версии /proc/stat и добавляя полученные числа к самому последнему набору (по крайней мере, я так думаю, я перейду этот мост, когда доберусь туда). Несмотря на это, я немного смущен тем, как анализировать информацию. Я знаю, что результаты выглядят так:

 cpu  1135030 3367 440838 5175504 85602 0 78716 0 0 0
cpu0 284682 935 110466 3027379 55475 0 27688 0 0 0
cpu1 282910 969 109421 719958 8029 0 22700 0 0 0
cpu2 284182 648 110727 715945 9275 0 16262 0 0 0
cpu3 283256 814 110223 712220 12822 0 12065 0 0 0
 

и я знаю, что верхняя строка представляет собой совокупность всех ядер, а строки представляют user, nice, system, idle, iowait, irq, softirq, steal, guest и guest_nice соответственно.

Мой исходный код :

 int main() {
    FILE *state1;
    FILE *state2;
    int oldNumbers[7];
    int newNumbers[7];

    state1 = fopen("/proc/stat", "r");
    sleep(1);
    state2 = fopen("/proc/stat", "r");

    fscanf(state1, "%d %d %d %d %d %d %d", oldNumbers[0], oldNumbers[1], oldNumbers[2], oldNumbers[3], oldNumbers[4], oldNumbers[5], oldNumbers[6]);
    fscanf(state2, "%d %d %d %d %d %d %d", newNumbers[0], newNumbers[1], newNumbers[2], newNumbers[3], newNumbers[4], newNumbers[5], newNumbers[6]);

    fclose(state1);
    fclose(state2);

    return 0;
}
 

Я понимаю, почему это не работает, поскольку мои oldNumbers[] и newNumbers[] не являются указателями, но когда я делаю их указателями, они тоже не работают. Тем не менее, я абсолютно не представляю, как двигаться дальше, и любой вклад был бы весьма признателен.

Спасибо

Ответ №1:

  • Вам не нужны два указателя на файл, только один, затем вы можете просто вернуться к началу файла для второго чтения.
  • Как уже упоминалось, вам необходимо использовать указатели в fscanf()
 #include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *statFP;
    int oldNumbers[7];
    int newNumbers[7];
    int diffNumbers[7];
    char cpu[10];  // Not used

    statFP = fopen("/proc/stat", "r");

    fscanf(statFP,
            "%s %d %d %d %d %d %d %d",
            cpu,
            amp;oldNumbers[0], 
            amp;oldNumbers[1],
            amp;oldNumbers[2],
            amp;oldNumbers[3],
            amp;oldNumbers[4],
            amp;oldNumbers[5],
            amp;oldNumbers[6]);

    sleep(1);
    rewind(statFP);

    fscanf(statFP,
            "%s %d %d %d %d %d %d %d",
            cpu,
            amp;newNumbers[0],
            amp;newNumbers[1],
            amp;newNumbers[2],
            amp;newNumbers[3],
            amp;newNumbers[4],
            amp;newNumbers[5],
            amp;newNumbers[6]);

    fclose(statFP);

    for (int ii = 0; ii < 7; ii  ) {
        diffNumbers[ii] = newNumbers[ii] - oldNumbers[ii];
        printf("%d: %dn", ii, diffNumbers[ii]);
    }
    return 0;
}
 

В качестве еще одного примечания существует пакет Linux под названием sysstat (https://github.com/sysstat/sysstat ), который содержит все виды кода для синтаксического анализа информации в /proc. Это стоит посмотреть.

Ответ №2:

Как минимум, вам нужно отсканировать начальную строку, прежде чем вы сможете отсканировать числа. Конечно, fscanf принимает указатели.

     fscanf(state1, "%*s %d %d %d %d %d %d %d", amp;oldNumbers[0], amp;oldNumbers[1], amp;oldNumbers[2], amp;oldNumbers[3], amp;oldNumbers[4], amp;oldNumbers[5], amp;oldNumbers[6]);
    fscanf(state2, "%*s %d %d %d %d %d %d %d", amp;newNumbers[0], amp;newNumbers[1], amp;newNumbers[2], amp;newNumbers[3], amp;newNumbers[4], amp;newNumbers[5], amp;newNumbers[6]);
 

После этого вам нужно будет отсканировать оставшиеся 3 числа, прежде чем вы сможете отсканировать ввод в следующей строке (если это то, что вы собираетесь делать).

И, /proc в основном, работает, предоставляя текущую информацию по мере чтения файла, а не заполняя что-либо при его открытии. Итак, вам нужно будет прочитать первый файл, затем подождать одну секунду, затем прочитать второй файл.

Комментарии:

1. Большое спасибо за помощь! Это сделало это намного проще. Ты спасатель, друг