Перейти до вмісту

B2. Власний mini-top

базовийспирається на модуль 2, модуль 6

Нічого магічного top не робить: він двічі читає текстові файли з /proc і ділить різницю на час. Написавши його самостійно, ви перестанете сприймати %CPU як число, що береться нізвідки, і зрозумієте, чому миттєвого завантаження процесора взагалі не існує.

Terminal window
./minitop # оновлення раз на секунду
./minitop --once # один знімок і вихід, зручно для перевірки
./minitop -n 10 # десять найважчих процесів

Мова будь-яка. Заборонено лише викликати top чи ps і розбирати їхній вивід — уся інформація береться з /proc.

Формат --once зафіксований, бо на нього спирається автоперевірка: один рядок заголовка, далі по рядку на процес із шістьма полями через пробіли, а наприкінці рядок підсумку за станами.

PID USER STATE CPU RSS NAME
1 root S 0.0 12484 systemd
842 michael R 99.3 3120 sh
...
states R=2 S=181 D=0 Z=1

CPU — відсоток одного ядра, RSS — у кілобайтах. NAME іде останнім і може містити пробіли, тому полів у рядку буває більше за шість — перші п’ять фіксовані, решта рядка є назвою. В інтерактивному режимі формат вільний: там ви робите вивід для людини.

Що Файл Поле
Список процесів /proc числові каталоги
Назва, стан, PPID /proc/<pid>/stat 2, 3, 4
Спожитий час /proc/<pid>/stat utime (14), stime (15)
Пам’ять /proc/<pid>/status VmRSS
Користувач /proc/<pid>/status Uid/etc/passwd
Час системи /proc/stat рядок cpu
Тиків на секунду getconf CLK_TCK
  1. Один знімок. Обійти /proc, зібрати назви й стани, вивести таблицю.

    Одразу закладіться на те, що процес може зникнути між тим, як ви побачили каталог, і тим, як відкрили в ньому файл. Це не виняткова ситуація, а звичайна.

  2. Завантаження процесора.

    Двічі прочитати utime + stime з інтервалом Δt і порахувати:

    %CPU = (Δ(utime + stime) / CLK_TCK) / Δt × 100

    Ось чому потрібні два виміри: у /proc лежить накопичений час від запуску процесу, а не поточне завантаження.

  3. Загальне завантаження системи.

    Те саме для рядка cpu з /proc/stat: різниця по кожному полю, частка не-idle у сумі. Стовпець iowait виведіть окремо — саме він відрізняє «бракує процесора» від «чекаємо на диск» (модуль 13).

  4. Сортування й оновлення. Топ-N за %CPU, оновлення раз на секунду.

  5. Підсумок за станами. Скільки процесів у R, S, D, Z. Запустіть поруч щось важке для диска й подивіться, як росте D.

Перевірка лежить в архіві з файлами курсу, і команди нижче виконуються з розпакованого каталогу.

Terminal window
cd labs/b2-mini-top
./check.sh ./minitop

Скрипт запускає навантаження з відомою поведінкою й перевіряє, що ваш монітор його бачить: знаходить процес, показує близький до очікуваного %CPU, помічає зомбі й не падає, коли процес зникає під час обходу.

Падіння на зниклому процесі. /proc/1234/stat перестає існувати між readdir і open, тож обробляйте ENOENT як норму, а не як помилку.

Назва процесу розбирається неправильно. Друге поле /proc/<pid>/stat береться в дужки й цілком може містити і пробіли, і дужки. Різати рядок пробілами не можна, шукайте останню ).

%CPU рахується за одним виміром. Тоді ви показуєте середнє за весь час життя процесу, а не поточне навантаження, і воно майже завжди близьке до нуля.

Забуто CLK_TCK. Значення в /proc вимірюються не в секундах, а в тиках, і сотня тут аж ніяк не константа стандарту.

VSZ замість RSS. Показує адресний простір, а не спожиту пам’ять (модуль 10).

Додати режим -H, який показує окремі потоки з /proc/<pid>/task, і подивитися на багатопотоковий процес (модуль 8).