Comments 20
С одной стороны стороны да, но вот как с помощью современных обёрток получить в шелл скрипте использованное процессом процессорное время с точностью хотя бы до сотой доли секунды без чтения /proc/$PID/stat
? У меня сейчас это используется в самописном плагине для munin.
Я провел небольшой эксперимент. Запустил 10000 процессов и запустил следующую команду:
# ps ax | wc -l
10091
# time for i in /proc/*/stat; do cat $i > /dev/null; done
cat: /proc/net/stat: Is a directory
real 0m21.923s
user 0m2.326s
sys 0m19.934s
20 секунд на 50K процессов. Имхо, это очень много.
Вы тут очень сильно передёргиваете. Во-первых, в ваших измерениях львиная доля времени тратится на порождение новых процессов, что для этой задачи просто не нужно. Если читать встроенными средствами шелла, то получается на порядок с лишним быстрее:
$ time for i in /proc/*/stat; do cat $i >/dev/null ; done
cat: /proc/net/stat: Is a directory
real 0m0,373s
user 0m0,238s
sys 0m0,156s
$ time for i in /proc/*/stat; do read STAT < $i; done
-bash: read: read error: 0: Is a directory
real 0m0,012s
user 0m0,002s
sys 0m0,011s
Во-вторых, мне не нужно мониторить все процессы. Сейчас проверил — у меня мониторится 5 конкретных процессов. В этой ситуации при том, что мой плагин написан аккуратно и не делает лишних форков, тратится на сбор данных пренебрежимо мало времени, считанные миллисекунды.
Не поймите неправильно. Я не считаю внедрение нового интерфейса вредным или ненужным — совсем наоборот! Я только приводил контраргумент к тезису "сейчас не бывает задач, для которых нужно читать напрямую из procfs".
Впрочем, я сейчас осознал, что если старый текстовый интерфейс будет выпилен и мой скрипт будет вынужден получать данные из внешней утилиты, то за счёт лишнего форка он станет капельку медленнее, что грустно.
Про то что ваш скрипт станет немного медленнее из-за лишнего форка, тут вы просто свой скрипт перепишите на python или любом другом языке, который сможет напрямую работать с новым интерфейсом и все будет хорошо.
Дело в том, что bash/grep/sed/awk и 5 минут вашего ЦЕННОГО времени — и задача чего-то там выщемить/отмониторить решена. Прямо тут, прямо сейчас. В 98% на этом можно остановится — ибо задача решена. Если по ходу видно, что надо бы сэкономить ресурсов — можно думать дальше.
Во-вторых, если вы говорите про grep, sed, awk и тп, то вы уже готовы запускать дополнительные процессы, а значит сможете запустить и дополнительную тулзу, которая выдаст вам нужные данные, полученные через новый интерфейс.
В-третьих, если мы идем чуть дальше и вместо shell начинаем использовать что-то вроде python, то с новым интерфейсом вам жить будет даже проще.
Во-первых, текущий /proc еще долго никуда не денется
Я вам только что доступно объяснил — почему.
мы идем чуть дальше
Несколько условно — идя в любимый барбершоп и дойдя до него, вы:
1. заходите вовнутрь
2. «идете чуть дальше» километра на полтора, затем возвращаетесь и уже тогда заходите вовнутрь
Вы предлагаете (2). Дело ваше — спорить не буду.
Как сухой остаток — те 2%, что остаются после 98%, тоже надо чем-то делать. И это хорошо, что инструмент и для этого тоже постепенно затачивают.
Смените тон и прочтите еще раз коментарий.
> Вы предлагаете (2). Дело ваше — спорить не буду.
В вашем примере, я как раз выбираю первый вариант. А второй вариант — это то как сейчас работает ps или top. Сначала ядро данные о процессах выдает в текстовом виде, потому утилита ps декодирует их к бинарному виду, обрабатывает и выдает в другом текстовом виде.
По поводу количества процессов. Если у вас речь идет о десятках процессов, то действительно проблем нет и с текущим интерфейсом.
Я все же предлагаю сравнить производительность task_diag и procfs для большого количества процессов.
Для эксперимента, я опять запустил 10000 процессов. Давайте теперь посмотрим сколько будет выполняться приведенный вами скрипт и получение тех же данных через task-diag.
# time for i in /proc/*/stat; do read STAT < $i; done
-bash: read: read error: 0: Is a directory
real 0m0.657s
user 0m0.138s
sys 0m0.515s
А теперь получим cputime через task_diag:
# time ./task_diag_all all -x -q
real 0m0.041s
user 0m0.000s
sys 0m0.039s
Для понимания, вот пример данных, которые мы получаем через task_diag:
# ./task_diag_all one -x -p 1
Start getting information about 1
pid 1 tgid 1 ppid 0 sid 1 pgid 1 comm systemd
minflt: 8658
cminflt: 8320191
majflt: 78
cmajflt: 670
utime: 155
stime: 3704
cutime: 5201
cstime: 16716
threads: 1
НаверноеЗПТ интересно было бы узнать, насколько быстрее был бы вывод, если бы использовались бинарные данные напрямую, и если бы не требовалось три системных вызова.
Попытки создать такой интерфейс уже были. В 2004 пробовали использовать netlink движок.
В Solaris было как раз так, как вы мечтаете. Открываешь /proc, а там вместо текстовичков — бинарные файлы. В результате эти файлы, кажется, даже ps с top'ом не читали — обращались напрямую к ядру с запросами.
Про какие бы новые фишки в Linux мы не говорили, всегда кто-то скажет, что в Солярис все это было.
Я не идеализирую Солярис, если вы об этом. Да и поработать под соляркой мне довелось недолго. Но да, это была прекрасно вылизанная, устойчивая и надежная операционная система с кучей продвинутых фишечек.
Почему ее не стало — вопрос настолько же провокационный, насколько и дурацкий. Но я вам попытаюсь ответить — так, как вижу со своей колокольни.
Поддержка коммерческой ОСи в актуальном состоянии — это большие расходы. Очень большие расходы. И эти расходы должны компенсироваться. Другими словами, ОСь должна приносить доход.
Очевидно, у фирмы SUN накопилось множество проблем, и разработка соляриса перестала быть прибыльной. Плюс активизировались конкуренты и заняли ниши, в которых раньше господствовал Сан. Оборудование на базе Интела стало дешевым, Линукс — несмотря на легкую топорность — все-таки оказался вполне работоспособным решением, и солярка умерла. Это бизнес.
К чести SUN, они сделали весьма многое, чтобы сохранить солярис. Проект OpenSolaris и портирование на архитектуру Intel — это по сути попытка сделать из солярки открытую операционную систему. Но — не срослось. Трижды тьфу на Оракл.
Судя по всему, это была ОС, которая сильно обогнала свое время.
Я бы не сказал, что она обогнала свое время. Скорее, это был продукт своего времени, но максимально вылизанный и хорошо продуманный. По крайней мере, такое впечатление он производил на неискушенного меня. :)
Зачем вы хотите из файловой системы proc читать бинарные данные? Читайте прямо из ядра.
А как это читать напрямую из ядра? Какие в линуксе еще есть способы получения информации о процессах? К примеру как их получает top/htop? Тормозов как описано в статье в htop я не замечал.
Спрашиваю, потому что не знаю, если знаете то просветите.
Если первое — флаг вам в руки, новый производительный бинарный интерфейс для утилит — это, наверное, хорошо.
Если второе — как справедливо писали выше, иногда из какого-нибудь скрипта или приложения нужно просто заглянуть во вполне конкретный файл и достать кусочек информации, не всем нужно парсить полную информацию обо всём дереве процессов, поэтому удалять plain text не очень хорошо.
А поддерживать два более-менее одинаковых интерфейса в ядре — накладно. Думаю, что в том числе и из-за этого ваше предложение буксует столько времени. Правда, как это решить я тоже не знаю.
И вы совершенно правы, вопрос о поддержке двух интерфейсов регулярно возникает. Сейчас код написан так, что большая его часть шарится между procfs и task_diag.
Насколько эффективна виртуальная файловая система procfs и можно ли ее оптимизировать