Изучаем процессы в linux

Вычисление средней загрузки

Средняя загрузка (Load Average, LA) — усредненная мера использования ресурсов компьютера запущенными процессами. Величина LA пропорциональна числу процессоров в системе и на ненагруженной системе колеблется от нуля до значения, равного числу процессоров. Высокие значения LA (10*число ядер и более) говорят о чрезмерной нагрузке на систему и потенциальных проблемах с производительностью.

В классическом Unix LA имеет смысл среднего количества процессов в очереди на исполнение + количества выполняемых процессов за единицу времени. Т.е. LA == 1 означает, что в системе считается один процесс, LA > 1 определяет сколько процессов не смогли стартовать, поскольку им не хватило кванта времени, а LA < 1 означает, что в системе есть незагруженные ядра.

В Linux к к количеству процессов добавили ещё и процессы, ожидающих ресурсы. Теперь на рост LA значительно влияют проблемы ввода/вывода, такие как недостаточная пропускная способность сети или медленные диски.

LA усредняется по следующей формуле LAt+1=(LAcur+LAt)/2. Где LAt+1 — отображаемое значение в момент t+1, LAcur — текущее измеренное значение, LAt — значение отображавшееся в момент t. Таким образом сглаживаются пики и после резкого падения нагрузки значение LA будет медленно снижаться, а кратковременный пик нагрузки будет отображен половинной величиной LA.

Что такое процесс?

Начнем с того, что разберемся в терминах. По сути, процесс — это каждая программа. Как я уже говорил для каждой запускаемой программы создается отдельный процесс. В рамках процесса программе выделяется процессорное время, оперативная память и другие системные ресурсы. У каждого процесса есть свой идентификатор, Proccess ID или просто PID, по ним, чаще всего и определяются процессы Linux. PID определяется неслучайно, как я уже говорил, программа инициализации получает PID 1, а каждая следующая запущенная программа — на единицу больше. Таким образом PID пользовательских программ доходит уже до нескольких тысяч.

На самом деле, процессы Linux не настолько абстрактны, какими они вам сейчас кажутся. Их вполне можно попытаться пощупать. Откройте ваш файловый менеджер, перейдите в корневой каталог, затем откройте папку /proc. Видите здесь кучу номеров? Так вот это все — PID всех запущенных процессов. В каждой из этих папок находится вся информация о процессе.

Например, посмотрим папку процесса 1. В папке есть другие под каталоги и много файлов. Файл cmdline содержит информацию о команде запуска процесса:

Поскольку у меня используется система инициализации Systemd, то и первый процесс запускается для нее. С помощью каталога /proc можно сделать все. Но это очень неудобно, особенно учитывая количество запущенных процессов в системе. Поэтому для реализации нужных задач существуют специальные утилиты. Перейдем к рассмотрению утилит, которые позволяют реализовать управление процессами в Linux.

Управление процессами в Linux

Также в Linux присутствуют некоторые команды для управления процессами:

   kill — посылает процессу сигнал завершения работы;

   pkill — завершает процесс по его имени;

   pgrep — ищет процесс по его имени (и, опционально, по имени запустившего его пользователя);

   killall — завершает все активные процессы.

Ниже приведены несколько основных примеров их использования:

Отправка сигналов процессам

Основополагающим способом управления процессами в Linux является отправка им соответствующих сигналов. Для перечисления списка всех доступных сигналов, введите команду:

Чтобы отправить процессу нужный сигнал, используйте команды , или , о которых мы упоминали ранее. Но программы могут реагировать на сигналы только в том случае, если они запрограммированы на распознавание этих сигналов.

Большинство сигналов предназначены для внутреннего использования системой или для программистов, когда они пишут код. Ниже приведены наиболее полезные сигналы:

   SIGHUP (1) — отправляется процессу, когда его управляющий терминал закрыт.

   SIGINT (2) — отправляется процессу управляющим терминалом, когда пользователь прерывает процесс нажатием клавиш Ctrl+C.

   SIGQUIT (3) — отправляется процессу, если пользователь посылает сигнал выхода Ctrl+D.

   SIGKILL (9) — этот сигнал немедленно завершает (убивает) процесс, и процесс не будет выполнять никаких операций очистки за собой.

   SIGTERM (15) — сигнал завершения программы (отправляется командой по умолчанию).

   SIGTSTP (20) — отправляется процессу управляющим терминалом с запросом на остановку; инициируется пользователем нажатием клавиш Ctrl+Z.

Ниже приведены примеры команды для уничтожения приложения с помощью PID, после его зависания:

или

или

Чтобы убить приложение, используя его имя, применяются команды или , например:

или

Изменение приоритета процесса

В системе Linux все активные процессы имеют определенный приоритет выполнения, задаваемый так называемым nice-значением. Процессы с более высоким приоритетом обычно получают больше процессорного времени, чем процессы с более низким приоритетом. Однако пользователь с root-правами может повлиять на это с помощью команд nice и renice.

Узнать значение приоритета команды можно по выводу команды (столбец NI):

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

Чем больше nice-значение, тем меньшим приоритетом будет обладать процесс. Например, вы можете задать приоритет для запускаемого процесса следующим образом:

Чтобы изменить приоритет уже запущенного процесса, используйте команду следующим образом:

На данный момент это всё! Если у вас есть какие-либо вопросы или дополнительные идеи, вы можете поделиться ими с нами с помощью комментариев.

Отслеживание активных процессов

Существует несколько различных инструментов для просмотра/перечисления запущенных в системе процессов. Двумя традиционными и хорошо известными из них являются команды ps и top:

Команда ps

Отображает информацию об активных процессах в системе, как показано на следующем скриншоте:

Для получения дополнительной информации о процессах, запущенных текущим пользователем, применяется опция :

Столбцы, присутствующие в выводе команды , имеют следующие значения:

   UID — идентификатор пользователя, которому принадлежит процесс (тот, от чьего имени происходит выполнение).

   PID — идентификатор процесса.

   PPID — идентификатор родительского процесса.

   C — загрузка CPU процессом.

   STIME — время начала выполнения процесса.

   TTY — тип терминала, связанного с процессом.

   TIME — количество процессорного времени, потраченного на выполнение процесса.

   CMD — команда, запустившая этот процесс.

Также можно отобразить информацию по конкретному процессу, используя команду , например:

Есть и другие опции, которые можно использовать вместе с командой :

    — показывает информацию о процессах по всем пользователям;

    — показывает информацию о процессах без терминалов;

    — показывает дополнительную информацию о процессе по заданному UID или имени пользователя;

    — отображение расширенной информации.

Если вы хотите вывести вообще всю информацию по всем процессам системы, то используйте команду :

Обратите внимание на выделенный заголовок. Команда поддерживает функцию сортировки процессов по соответствующим столбцам

Например, чтобы отсортировать список процессов по потреблению ресурсов процессора (в порядке возрастания), введите команду:

Результат:

Если вы ходите выполнить сортировку по потреблению памяти (в порядке убывания), то добавьте к имени интересующего столбца знак минуса:

Результат:

Еще один очень популярный пример использования команды — это объединение её и для поиска заданного процесса по его имени:

Результат:

Команда top

Команда top отображает информацию о запущенных процессах в режиме реального времени:

Рассмотрим детально:

   PID — идентификатор процесса.

   USER — пользователь, которому принадлежит процесс.

   PR — приоритет процесса на уровне ядра.

   NI — приоритет выполнения процесса от до .

   VIRT — общий объем (в килобайтах) виртуальной памяти (физическая память самого процесса; загруженные с диска файлы библиотек; память, совместно используемая с другими процессами и т.п.), используемой задачей в данный момент.

   RES — текущий объем (в килобайтах) физической памяти процесса.

   SHR — объем совместно используемой с другими процессами памяти.

   S (сокр. от «STATUS») — состояние процесса:

   S (сокр. от «Sleeping») — прерываемое ожидание. Процесс ждет наступления события.

   I (сокр. от «Idle») — процесс бездействует.

   R (сокр. от «Running») — процесс выполняется (или поставлен в очередь на выполнение).

   Z (сокр. от «Zombie») — зомби-процесс.

   %CPU — процент используемых ресурсов процессора.

   %MEM — процент используемой памяти.

   TIME+ — количество процессорного времени, потраченного на выполнение процесса.

   COMMAND — имя процесса (команды).

Также в сочетании с основными символами состояния процесса (S от «STATUS») вы можете встретить и дополнительные:

    — процесс с высоким приоритетом;

    — процесс с низким приоритетом;

    — многопоточный процесс;

    — фоновый процесс;

    — лидер сессии.

Примечание: Все процессы объединены в сессии. Процессы, принадлежащие к одной сессии, определяются общим идентификатором сессии — идентификатором процесса, который создал эту сессию. Лидер сессии — это процесс, идентификатор сессии которого совпадает с его идентификаторами процесса и группы процессов.

Команда glances

Команда glances — это относительно новый инструмент мониторинга системы с расширенными функциями:

Примечание: Если в вашей системе отсутствует данная утилита, то установить её можно с помощью следующих команд:

RHEL/CentOS/Fedora

Debian/Ubuntu/Linux Mint

Юниты systemd.

Прежде всего, нужно разобраться что такое юнит, что означают его статус, и как их фильтровать. Unit — это описание сервиса в текстовом виде, где указаны операции, которые должны быть выполнены до и после запуска службы. Юнит — это описание параметров системы инициализации.

Наиболее часто, управление демонами происходит командами start|stop|reload|status|enable|disable. Для примера, мы можем проверить статус демона как каноничной подсистемы инициализации init (он же System V или SysV):

root@dedicated:~ /etc/init.d/nginx status

Общая команда будет иметь следующий вид:

root@dedicated:~ sudo service nginx status

…или выполнить тоже самое с помощью systemd:

root@dedicated:~ systemctl status nginx.service

Посмотреть список всех запущенных юнитов можно командой:

root@dedicated:~ systemctl

Мы увидим список всех запущенных юнитов, а так же их статус.

UNIT — имя юнита

LOAD — информирует нас о успешной загрузке конфигурации.

ACTIVE — Активный ли юнит.

SUB — более детальная системная информация о юните.

DESCRIPTION — краткое описание.

На скриншотах выше, в колонке UNIT, после префикса, указан тип юнита. Например *.service указывает, что юнит указывает на службу (nginx, apache и т.д.). Существует несколько возможных видов юнитов (socket, device, mount, swap, automount, target, snapshot, timer и другие)

На данный момент многие из них нам не пригодятся, потому рассмотрим базовый *.service, на которые стоит обратить внимание. Задача на данный момент — указать путь, а не запутать читателя

Ссылка на руководство по углубленному изучению будет предоставлена в конце статьи.

Отфильтруем только службы:

root@dedicated:~ systemctl list-units --type=service

Отфильтруем неактивные юниты:

root@dedicated:~ systemctl list-units --all --state=inactive

Существуют следующие статусы: active, inactive, running, exited, dead, loaded, not-found, plugged, mounted, waiting, listening.

Посмотреть самую полную информацию, включая юниты, которые система по какой-то причине не загрузила:

root@dedicated:~ systemctl list-units --all

Отобразить список зависимостей определенного юнита

root@dedicated:~ systemctl list-dependencies nginx.service

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

DnD совместно работают над sysvinit

И теперь наконец-то хорошие новости! В последнее время наметились подвижки между группами разработчиков СИ Debian и Devuan. Решено объединить усилия по нескольким направлениям.

  • Поддерживать на плаву sysvinit для тех, кто готов использовать Debian Linux со всеми ограничениями, в т. ч. без графического окружения. Требуется помощь Devuan-цев в подготовке 10-й версии Debian, получившей название Buster.
  • В результате подобного «перекрестного опыления» Debian-щики помогли коллегам из Devuan в подготовке выпуска sysvinit 2.92. Благодаря этому сроки сократились и выпуск состоялся до НГ, как было сказано в начале поста.

Если здравый смысл возобладает то обе группы разработчиков смогут поставить и реализовать более актуальные для всех пользователей Debian/Devuan цели — добиться полноценной поддержки нескольких СИ для Devuan Linux: , , , и т. д. Так же и Debian Linux полноценная поддержка хотя бы одной отличной от systemd СИ несомненно пошла бы на пользу.

P. S. В Амсдердаме 5-7 апреля 2019 г. пройдет первая конференция Devuan Linux.

Дополнительное чтение

  • Init system support in Debian
  • Why ‘init’ Needed to be Replaced with ‘systemd’ in Linux
  • Collaboration between Devuan and Debian leads to new sysvinit release
  • GNOME Without Systemd

Уровни исполнения (runlevels)

В отличие от прочих систем инициализации, у уровней исполнения в Gentoo нет строго определенных имен или номеров, но сходства с init есть. Существуют три уровня исполнения по умолчанию: «boot», «default» и «nonetwork».

Уровень исполнения «boot» должен быть стандартным для большинства
установок и, как следует из его названия, это первый уровень исполнения, запускаемый на стадии загрузки. Следующий — «default» — это главный уровень исполнения, исполняющийся после загрузки — что и отражено в его названии. И последний уровень, «nonetwork», выступает исключительно в качестве примера.

Уровни исполнения расположены в /etc/runlevels, в поддиректории,
названной по имени уровня исполнения; эта поддиректория заполняется
символическими ссылками на сервисы, относящиеся к данному уровню
исполнения.

Наиболее предпочтительный способ добавления или удаления сервисов
обсуждается в разделе «О rc-update».

Как показано ранее, имя уровня исполнения можно изменить на более
подходящее пользователю, поскольку для отражения нового имени также
меняется и запись правила в /etc/inittab.

Однако, из этого правила есть исключение: уровень исполнения «boot». Пожалуйста, НЕ меняйте имя уровня исполнения «boot», так как это может привести к неприятным последствиям!

Всю работу (в том числе и переключение уровней исполнения на лету)
выполняет сценарий /sbin/rc.

Использование библиотеки musl

Приведенные выше редакции доступны также в отдельных версиях, основанных на библиотеке musl. Распространяются в ISO файлах вида: void-live-arch-musl-*.iso

musl — это библиотека языка программирования C.

Для справки: Самой распространенной версией библиотеки языка программирования C является glibc (GNU C Library). Именно glibc используется в большинстве популярных дистрибутивов Linux.

musl — это альтернативная реализация стандартной библиотеки языка С (libc) для Linux. Она была разработана в начале 2010-х и является относительно молодой. musl не является форком какой-то другой библиотеки и была написана с нуля.

Целью создания musl являлось написать более легковесную, эффективную и чистую реализацию стандартной библиотеки и при этом полностью соответствовать стандартам.

musl получилась небольшой, обеспечивает хорошую производительность, имеет низкое потребление ресурсов.

musl распространяется по лицензии MIT и ее можно использовать в закрытых проектах.

Systemd

Systemd — это новая система инициализации Linux. Она была введена по умолчанию в Fedora 15, а сейчас используется почти во всех популярных Linux дистрибутивах. Это не только инициализирующий процесс, поддерживающий огромное количество возможностей, но и набор инструментов для управления службами и этими возможностями из системы. Основная цель — иметь полный контроль над всеми процессами во время их запуска и на протяжении всего выполнения.

Systemd очень сильно отличается от всех существующих систем инициализации, тем как она работает с сервисами, и даже конфигурационными файлами сервисов. Совместимости со скриптами SysV нет, их нужно преобразовать в linux systemd unit файлы.

Вот ее основные особенности:

  • Понятный, простой и эффективный дизайн;
  • Параллельная загрузка служб на основе зависимостей;
  • Лучший APIv;
  • Поддерживается завершение дополнительных процессов;
  • Поддерживается собственный журнал с помощью journald;
  • Поддерживается планирование заданий с помощью таймеров Systemd;
  • Хранение журналов в бинарных файлах;
  • Сохранение состояния сервисов linux systemd для возможного восстановления;
  • Улучшенная интеграция с Gnome;
  • Запуск сервисов по требованию;

Удаление завершенного процесса из таблицы процессов

После завершения процесса его остается занят — это состояние процесса называется «зомби». Чтобы освободить родительский процесс должен дождаться завершения дочернего и очистить таблицу процессов. Это достигается вызовом:

Вызов эквивалентен

ждет завершения дочернего процесса и возвращает его . Код завершения и обстоятельства завершения заносятся в переменную status. Дополнительно, поведением можно управлять через параметр options.

  • pid < -1 — ожидание завершения дочернего процесса из группы с pgid==-pid
  • pid == -1 — ожидание завершения любого дочернего процесса
  • pid == 0 — ожидание завершения дочернего процесса из группы, pgid которой совпадает с pgid текущего процесса
  • pid > 0 — ожидание завершения любого дочернего процесса с указанным pid

Опция WNOHANG — означает неблокирующую проверку завершившихся дочерних процессов.

Статус завершения проверяется макросами:

«Ключевой вопрос математики: не всё ли равно» ©

Что, если вам нужно узнать, ссылается ли этот файловый дескриптор на ? Казалось бы, — и все дела. Ну, окей…

Упс… Дескриптор-то вроде как один, но алиасы разные. Нам поможет CRIU — Checkpoint/Restore In Userspace. Без паники, я не предлагаю сдампить процесс, посмотреть на результат и загрузить обратно. Просто для нужд своих userspace-инструментов, разработчики из этого проекта, как я понял, добавили в ядро системный вызов : ему передаются два PID, тип ресурса и, собственно, два ресурса, а он говорит, указывают ли они на одну и ту же сущность ядра:

Опять двадцать пять! Подождите ка, а что если…

Ага, тот неловкий момент, когда пытаешься понять, где ошибка, а она оказалась в твоём понимании происходящего. Логично считать, что bash точно так же поступает и с моей программой, как и с !

Не буду утверждать, что это работает всегда и идеально — для этого нужно самому его использовать много и по-разному, но как best effort инструмент для каких-нибудь эвристик наверняка может пригодиться.

Автозагрузка служб в systemd

Как вы знаете, systemd позволяет автоматически загружать службы при запуске системы по мере их надобности. Команда list-unit-files показывает добавлена ли служба в автозагрузку.

Вообще, здесь может быть несколько состояний — enabled — в автозагрузке, disabled — автозагрузка отключена, masked — служба скрыта и static — значит что служба в автозагрузке, но вы не можете ее отключить.

Поэтому чтобы получить список служб linux, запускаемых автоматически достаточно отфильтровать ее вывод по состоянию:

Все службы, запускаемые по умолчанию. Можете также посмотреть службы static. Чтобы добавить службу в автозагрузку linux используйте команду enable:

А для того чтобы убрать ее из автозагрузки:

Также, вы можете посмотреть разрешена ли сейчас автозагрзука для службы:

Утилита просто выведет состояние enabled, disabled или static.

Об авторах

Daniel Robbins

Дэниэль Роббинс — основатель сообщества Gentoo и создатель операционной системы Gentoo Linux. Дэниэль проживает в Нью-Мехико со свой женой Мэри и двумя энергичными дочерьми. Он также основатель и глава Funtoo, написал множество технических статей для IBM developerWorks, Intel Developer Services и C/C++ Users Journal.

Chris Houser

Крис Хаусер был сторонником UNIX c 1994 года, когда присоединился к команде администраторов университета Тэйлора (Индиана, США), где получил степень бакалавра в компьютерных науках и математике. После он работал во множестве областей, включая веб-приложения, редактирование видео, драйвера для UNIX и криптографическую защиту. В настоящий момент работает в Sentry Data Systems. Крис также сделал вклад во множество свободных проектов, таких как Gentoo Linux и Clojure, стал соавтором книги The Joy of Clojure.

Aron Griffis

Эйрон Гриффис живет на территории Бостона, где провел последнее десятилетие работая в Hewlett-Packard над такими проектами, как сетевые UNIX-драйвера для Tru64, сертификация безопасности Linux, Xen и KVM виртуализация, и самое последнее — платформа HP ePrint. В свободное от программирования время Эйрон предпочитает размыщлять над проблемами программирования катаясь на своем велосипеде, жонглируя битами, или болея за бостонскую профессиональную бейсбольную команду «Красные Носки».

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Ваша ОС
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: