B2. Власний mini-top
Машина гальмує, ви відкриваєте top, і перше запитання: чи вірити
стовпцю %CPU. Нічого магічного top не робить: він двічі читає
текстові файли з /proc і ділить різницю на час. У цій роботі ви
напишете такий монітор самі й побачите те, що описують
модуль 6 про стани процесу і /proc
і модуль 2 про таймер, який лічить тики.
Після цієї роботи ви зможете:
- обійти
/procі зібрати по кожному процесу назву, стан, користувача, спожитий час і RSS; - порахувати
%CPUза різницею двох вимірів і пояснити, чому один вимір дає середнє за все життя процесу; - прочитати рядок
cpuз/proc/statі відрізнити «бракує процесора» від «чекаємо на диск» заiowait; - розібрати
/proc/<pid>/statдля процесу, у назві якого є пробіл чи дужка, без зсуву полів; - пояснити за підсумком станів, що означає зростання
DабоZ.
Це та сама робота, яку роблять, коли top показує 100% на ядрі,
а причина неочевидна: перевірити, звідки взялося число, скільки процесів
чекають на диск і чи не накопичуються зомбі.
Завдання
Section titled “Завдання”Написати програму minitop, яка читає /proc і показує процеси
з їхнім поточним завантаженням процесора, у трьох режимах:
./minitop # оновлення раз на секунду./minitop --once # один знімок і вихід, зручно для перевірки./minitop -n 10 # десять найважчих процесівЩо має вміти:
- обходити
/procі не падати, коли процес зникає міжreaddirіopen; - показувати по кожному процесу PID, користувача, стан,
%CPU, RSS і назву; - рахувати
%CPUза різницеюutime + stimeміж двома вимірами, у режимі--onceтеж: процес, який щойно вантажив процесор і заспокоївся, має показувати близьке до нуля; - показувати загальне завантаження з рядка
cpuу/proc/stat,iowaitокремо; - сортувати за
%CPUі показувати перші N за-n; - підсумовувати стани: скільки процесів у
R,S,D,Z; - розбирати назву з пробілами й дужками без зсуву полів;
- у режимі
--onceзавершуватися самостійно: автоперевірка чекає на знімок не більше 20 секунд.
Формат --once зафіксований, бо на нього спирається автоперевірка:
один рядок заголовка, далі по рядку на процес із шістьма полями
через пробіли, а наприкінці рядок підсумку за станами.
PID USER STATE CPU RSS NAME1 root S 0.0 12484 systemd842 michael R 99.3 3120 sh...states R=2 S=181 D=0 Z=1CPU показує відсоток одного ядра, RSS подано в кілобайтах. NAME іде останнім
і може містити пробіли, тому полів у рядку буває більше за шість:
перші п’ять фіксовані, решта рядка є назвою. В інтерактивному режимі
формат вільний: там ви робите вивід для людини.
Чого робити не треба. Потоки, дерево процесів, кольори й керування
з клавіатури до цієї роботи не входять. Автоперевірка дивиться лише
на вивід --once.
Обмеження. Мова будь-яка. Заборонено лише викликати top чи ps
і розбирати їхній вивід: уся інформація береться з /proc.
Що записати у звіт:
- як ви ділите
%CPU: на одне ядро чи на всі, і що показують два зациклені процеси на одному ядрі; - значення
getconf CLK_TCKна вашій системі й де воно входить у формулу; - скільки процесів у стані
Dви побачили під важким дисковим навантаженням порівняно зі спокійною системою; - що сталося з першим варіантом програми, коли процес зник під час обходу, і як ви це обробили.
Готово, коли:
./check.sh ./minitopпроходить усі п’ятнадцять перевірок;- зациклений
sh -c 'while :; do :; done'показує у вашому моніторі близько 100%, а той самий процес після зупинки циклу близько 0%; - у звіті є чотири пункти вище.
Перед початком
Section titled “Перед початком”- Прочитайте в модулі 6 розділи «Стани і переходи»,
«Зомбі та сироти» і «Як це насправді в Linux» (частину про
/proc/self/status), а в модулі 2 розділи «Переривання і винятки» і «Як це насправді в Linux» (частину про/proc/interrupts). - Розпакуйте архів курсу: перевірка лежить
у
labs/b2-mini-top/check.sh. - Знадобляться
getconf CLK_TCK,man 5 procіtopдля звірки. Підійде будь-який Linux, зокрема контейнер і WSL2.
Звідки що брати
Section titled “Звідки що брати”| Що | Файл | Поле |
|---|---|---|
| Список процесів | /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 |
-
Один знімок. Обійти
/proc, зібрати назви й стани, вивести таблицю.Одразу закладіться на те, що процес може зникнути між тим, як ви побачили каталог, і тим, як відкрили в ньому файл. Це звичайна ситуація.
-
Завантаження процесора.
Двічі прочитати
utime + stimeз інтерваломΔtі порахувати:%CPU = (Δ(utime + stime) / CLK_TCK) / Δt × 100Два виміри потрібні тому, що в
/procлежить накопичений час від запуску процесу, а не поточне завантаження. -
Загальне завантаження системи.
Те саме для рядка
cpuз/proc/stat: різниця по кожному полю, частка не-idleу сумі. Стовпецьiowaitвиведіть окремо: він відрізняє «бракує процесора» від «чекаємо на диск» (модуль 13). -
Сортування й оновлення. Топ-N за
%CPU, оновлення раз на секунду. -
Підсумок за станами. Скільки процесів у
R,S,D,Z. Запустіть поруч щось важке для диска й подивіться, як ростеD.
Автоперевірка
Section titled “Автоперевірка”Перевірка лежить в архіві з файлами курсу, і команди нижче виконуються з розпакованого каталогу.
cd labs/b2-mini-top./check.sh ./minitopСкрипт запускає навантаження з відомою поведінкою й перевіряє, що ваш
монітор його бачить: знаходить процес, показує близький до очікуваного
%CPU, помічає зомбі й не падає, коли процес зникає під час обходу.
Часті помилки
Section titled “Часті помилки”Падіння на зниклому процесі. /proc/1234/stat перестає існувати
між readdir і open, тож обробляйте ENOENT як звичайну ситуацію.
Назва процесу розбирається неправильно. Друге поле /proc/<pid>/stat
береться в дужки й цілком може містити і пробіли, і дужки. Різати рядок
пробілами не можна, шукайте останню ).
%CPU рахується за одним виміром. Тоді ви показуєте середнє за весь
час життя процесу замість поточного навантаження, і воно майже завжди близьке
до нуля.
Забуто CLK_TCK. Значення в /proc подано в тиках, не в секундах,
і сотня тиків на секунду стандартом не гарантована.
VSZ замість RSS. Показує адресний простір, а не спожиту пам’ять
(модуль 10).
Далі, якщо цікаво
Section titled “Далі, якщо цікаво”Додати режим -H, який показує окремі потоки з /proc/<pid>/task,
і подивитися на багатопотоковий процес (модуль 8).