Вопрос или проблема
Для длительных процессов, таких как init, я могу делать такие вещи, как
$ cat /proc/[pid]/io
Что я могу сделать, если хочу увидеть статистику для кратковременно работающего процесса, например, утилиты командной строки, такой как ls? Я даже не знаю, как увидеть pid для такого кратковременно работающего процесса…
В основном, похоже, вы хотите общие советы по профилированию ввода-вывода приложения во время его работы. Вы делали это с помощью /proc/$PID/io
, что даст вам некоторое представление о том, сколько пропускной способности используется между диском и памятью для приложения. Мониторинг этого файла может дать вам грубое представление о том, что делает процесс, но это неполная картина, так как она показывает только, сколько данных передается на диск и обратно.
Чтобы решить заявленную вами проблему, у вас есть следующие варианты:
-
Используйте инструментировку платформы. В Linux написание скрипта SystemTap является самым полным решением, но в зависимости от того, насколько глубоко вы хотите это сделать, это может потребовать больше усилий, чем вы действительно готовы потратить для достижения желаемого результата.
-
Используйте инструментировку на уровне приложения. Существует много способов сделать это, но gprof profile является популярным вариантом. Некоторые приложения также могут предоставлять свою собственную инструментировку, но это нужно проверить.
Вероятно, лучший вариант – использовать уже существующие инструменты инструментировки платформы вместе, чтобы достичь желаемого эффекта и максимально это использовать.
Я не знаю о программе, которая запустит приложение и сделает все это за вас (это не означает, что такой программы нет, просто я о ней не слышал), поэтому ваш лучший выбор – просто начать сбор информации по всей системе и затем фильтровать по интересующему вас PID после факта (чтобы получить полный образец).
Прежде всего, я бы включил аудит вызовов execve
, чтобы вы могли сохранить PID запускаемого вами приложения. Как только у вас будет PID, вы сможете удалить аудит.
Запустите mount debugfs -t debugfs /sys/kernel/debug
, чтобы активировать debugfs, чтобы вы могли запустить blktrace
.
На моей системе я запустил blktrace -d /dev/sda -a read -a write -o - | blkparse -i -
, но вы можете настроить это. Вот пример вывода blktrace:
8,0 15 3 1266874889.709440165 32679 Q W 20511277 + 8 [rpc.mountd]
В приведенном выше выводе пятой столбец (32679
) – это PID, связанный с приложением, выполняющим запись. Части, которые нас интересуют – это Q
(тип события, в очереди), W
(поле RWBS, W
означает, что это запись, так как в этом поле нет S
, что также подразумевает, что это была асинхронная запись.) и 20511277 + 8
(операция начинается с номера блока 20511277 и продолжается еще на восемь блоков). Определение размеров чтения/записи должно просто складывать блоки и умножать на размер блока.
blktrace
также сообщит вам больше, чем просто объем передачи, он также покажет, если происходит что-то, связанное с объединениями, что вас интересует.
Как только вы запустите blktrace, вы можете запустить процесс, используя strace -c, который даст вам представление о средней задержке, связанной с каждым системным вызовом (включая операции read
и write
). В зависимости от того, насколько точным должно быть каждое выполнение, задержка может быть важной, а также это может сказать вам больше о том, что делает приложение (чтобы указать области для исследования настройки) без какой-либо инструментировки приложения.
С помощью этих двух инструментов вы должны получить довольно хорошую выборку того, что делает ваша программа, не теряя никаких данных или, возможно, включая ввод-вывод других приложений. Очевидно, есть больше способов сделать это, чем то, что я описал, но именно так я бы решил эту проблему.
Также можно собрать меры задержки, связанные с вводом-выводом, изменяя параметры вывода blkparse
, например. Я просто не делал этого, потому что недостаточно экспериментировал с ними.
Вы можете запустить команду в фоновом режиме, а затем получить ее pid через переменную $!
.
Пример:
$ ls & cat /proc/$!/io
[1] 6410
rchar: 7004
wchar: 0
syscr: 13
syscw: 0
read_bytes: 0
write_bytes: 0
cancelled_write_bytes: 0
Если приложение является единичным процессом, который вы можете запустить, и вы хотите получить счетчики ввода-вывода процесса в конце, то этот ответ может быть полезен:
Он работает, сохраняя счетчики ввода-вывода процесса оболочки из /proc/[pid]/io/
в переменной окружения перед запуском процесса, а затем вычитая их после окончания процесса.
Системный вызов Linux waitid
может сообщить довольно много информации о завершенном процессе, однако вам нужно использовать функцию syscall()
, чтобы вызвать его с необязательным параметром rusage
. Смотрите “man 2 waitid” для деталей.
Вам нужно будет написать небольшую программу, чтобы вызвать fork()
, execve(argv[1], argv+1, …)
и syscall(_NR_waitid,…)
, а затем сообщить о результатах.
Ответ или решение
Чтобы получить статистику ввода-вывода для кратковременно работающего процесса в Linux, например, для утилиты командной строки ls
, вы можете использовать несколько подходов, так как стандартный доступ к PID таких процессов может быть затруднён.
Подход 1: Использование фоновых процессов
Вы можете запустить процесс в фоновом режиме и получить его PID с помощью переменной $!
. Вот пример выполнения команды:
$ ls & # Запускаем ls в фоновом режиме
[1] 6410 # Здесь 6410 - это PID запущенного процесса
$ cat /proc/$!/io # Читаем статистику I/O для данного процесса
Подход 2: Использование инструментария для профилирования
-
Инструменты системного профилирования: Можно использовать
blktrace
в сочетании сblkparse
, что даст вам данные о операций ввода-вывода на уровне блочного устройства.mount debugfs -t debugfs /sys/kernel/debug # Монтируем debugfs blktrace -d /dev/sda -a read -a write -o - | blkparse -i - # Запускаем blktrace
После этого вы сможете запустить ваш процесс и отследить вывод, который будет содержать PID и информацию о чтениях и записях.
-
Системные вызовы и
strace
: Для мониторинга системных вызовов можно использоватьstrace
:strace -c -o output.txt ls # Выполняем ls и сохраняем статистику
Вывод
strace
сообщит о числе вызовов для операций ввода-вывода, которые были выполнены процессом.
Подход 3: Аудит системных вызовов
Вы можете включить аудит на системных вызовах, таких как execve
. Для этого вам нужно будет настроить аудиторскую подсистему Linux, чтобы отслеживать PID процесса, который вы хотите проанализировать.
Подход 4: Сравнительный анализ
Если вы запустите процесс и хотите получить данные о вводе-выводе до и после его выполнения, вы можете сначала получить текущее состояние через /proc/PID/io
, затем запустить процесс и снова прочитать статистику I/O. Разница даст вам информацию о том, что именно произошло в процессе.
Пример использования переменной окружения
Если ваше приложение является однопроцессным, вы можете сохранить счетчики I/O в переменной окружения перед его запуском и вычесть их после завершения. Это позволит вам получить точные значения ввода-вывода для запускаемого процесса.
Программное решение с waitid
Вы также можете написать небольшую программу, используя fork()
, execve()
и syscall(waitid)
, чтобы собрать результаты непосредственно после завершения процесса. Это потребует немного большего программирования, но даст точные результаты.
Заключение
Все вышеперечисленные методы позволят вам получить представление о статистике I/O для кратковременно выполняющихся процессов в Linux. Используйте тот метод, который наиболее подходит для ваших целей и текущего окружения.