Из этой статьи вы узнаете, что такое процессы, зачем они нужны и как работают в операционных системах Linux.
Что такое процесс
Процесс — это среда выполнения для работы экземпляра программы. Например, есть какая-то программа и при её запуске, для неё создается процесс. Этот процесс наделяется некоторыми свойствами, ему выделяется часть оперативной памяти и присваивается уникальный идентификатор. Программа работает в рамках этого процесса. Дополнительно вы можете прочитать о процессе на wikipedia.
Процессор обрабатывает эти процессы не одновременно. Он очень быстро переключается с одного процесса на другой, за счет чего возникает ощущение многозадачности.
С процессом связан целый ряд атрибутов, которые расширяют или ограничивают его возможности. В течение жизни процесс может находится в разных состояниях.
Жизнь процесса начинается с рождения, совсем как у человека. Еще одно сравнение с человеком, то что процесс может порождать другие процессы. Так процессы в Linux делятся на родительские и дочерние по отношению друг к другу. Например, когда вы работаете в терминале, вы работаете с интерпретатором bash, который работает в своем процессе. И если вы запускаете какую-нибудь команду, например ls, то процесс программы bash запускает процесс для программы ls. При этом bash становится родительским процессом для ls, а ls дочерним для bash.
Единственный процесс, который запускается не другим процессом а ядром, это процесс инициализации системы. Он запускается самым первым и запускает все остальные процессы в Linux. Его атрибут PID (идентификатор процесса) равен 1.
Когда процесс завершает свою работу, он сообщает об этом родительскому процессу и освобождает все свои ресурсы, кроме атрибута PID. Удалить PID умершего процесса должен его родитель. Пока он этого не сделает умерший процесс остается в состоянии «zombie». Но об этом позже.
Память процесса
Если процесс запущен на 32 разрядной операционной системе, то максимум ему система сможет выделить 2^32 = 4GB памяти. Если же это 64 разрядная операционная система, то теоретически процесс сможет получить 2^48=256TB памяти. В эту оперативную память загружается:
- code — код программы и код всех библиотек нужных программе;
- data — данные и библиотеки с которыми работает программа;
- stack — стек вызовов, когда одна часть программы вызывает другую, а та третью, и все эти вызовы запоминаются здесь;
- heap — куча, когда программе потребовалось выделить определенный объем памяти, который не был заранее известен и выделен.
Если для кода и данных память выделяется стразу в момент рождения процесса, то стек и куча может расти или уменьшаться. Для этого используется виртуальная (выделенная) память.
Типы процессов
В системе Linux существуют разные типы процессов.
Пользовательские процессы — работают от имени обычной учетной записи пользователя и выполняются в пространстве пользователя. Если процесс не запущен таким образом, который дает процессу дополнительные разрешения, то пользовательский процесс не имеет доступа к файлам в системе, к которым не имеет доступа сам пользователь запустивший процесс.
Процессы-демоны — предназначенные для работы приложения в фоновом режиме. Такие процессы обычно управляются какими-нибудь службами (сервисами SystemD). Процесс-демон может прослушивать входящие запросы к службе. Например apache2 является процессом-демоном и прослушивает запросы на просмотр веб-страниц. Такие процессы могут работать от имени root, или от имени специальных системных пользователей.
Процессы ядра — выполняются только в пространстве ядра. Они похожи на процессы-демоны. Основное отличие состоит в том, что процессы ядра имеют полный доступ к структурам ядра. Процессы ядра не так гибки, как процессы-демоны. Вы можете изменить поведение процесса-демона, изменив конфигурационные файлы и перезагрузив службу, но для изменения процессов ядра может потребоваться перекомпиляция ядра.
Атрибуты процессов
Каждый процесс имеет набор атрибутов, например:
- pid — идентификатор процесса;
- ppid — идентификатор родительского процесса;
- tty — управляющий терминал, с которого поступает ввод и на который поступает вывод. То есть stdin, stderr, stdout;
- sid — идентификатор сеанса;
- ruid — идентификатор пользователя запустившего исполняемый файл;
- rgid — идентификатор группы пользователя запустившего исполняемый файл;
- euid — идентификатор фактического пользователя от имени которого работает процесс;
- egid — идентификатор фактической группы от имени которой работает процесс;
- pgid — идентификатор группы процессов;
- tpgid — идентификатор терминальной группы процессов (forefraund group);
- pri — приоритет работы процесса, чем выше значение, тем выше приоритет. Пользователь, даже root не может менять это значение;
- ni — любезность процесса, от него зависит pri. Чем выше ni, тем ниже pri. Только root может менять это значение;
- s — состояние в котором находится процесс.
Это не весь список атрибутов, на самом деле их больше.
Состояния процессов
Процесс либо обрабатывается процессором, либо ожидает. Только один процесс может обрабатываться на одном ядре процессора. Все остальные процессы должны ждать или находиться в каком-то другом состоянии.
- R (running). Процесс обрабатывается на ЦПУ.
- R (runnable). Процесс готов к обработке и находится в очереди к ЦПУ. Running и runnable обозначаются одинаковой буквой R.
- D (uninterruptible sleep). Когда процесс обращается к устройству, например к диску или сетевой карте, он переходит в это состояние. А возвращается из него только после получения информации. Обычно в таком состоянии процесс находится не долго, но перестает обрабатывать любые сигналы. И если что-то пойдет не так, то завершить зависший процесс, не перезагружая сервер, не получится.
- I (Idle). Бездействующий поток ядра. Состояние похоже на D, но такие процессы не нагружают процессор и исключены из расчета load average.
- S (sleeping). Процесс ожидает какие-то ресурсы, которые в данный момент недоступны. При переходе в это состояние, процесс немедленно отказывается от доступа к процессору. Когда ресурс, который ожидает процесс, становится доступным, процесс может снова перейти в состояние R (runnable). В спящем состоянии процесс продолжает обрабатывать сигналы.
- T (stopped by job control signal). Остановленный специальным сигналом. Это состояние похоже на паузу, то есть из этого состояния процесс может выйти и продолжить свою работу в состоянии R или S.
- t (stopped by debugger during trace). Остановлен отладчиком. Состояние подобное T, но в этом случае остановка процесса произошла во время отладки.
- Z (zombie). Когда процесс завершает свою работу, он освобождает свои ресурсы, но не освобождает свой PID в таблице процессов. Вместо этого он отправляет сигнал родителю, сообщая что он завершается. Родительский процесс должен освободить PID дочернего процесса. Отрезок времени между завершением процесса и когда родитель освободит его PID называется состоянием зомби. Процесс может остаться в состоянии Zombie, если родительский процесс умрет до того, как освободит PID дочернего процесса.
Утилиты для анализа процессов
Часто для наблюдением за процессами использую утилиты top, htop и ps.
Утилиты top и htop — это интерактивные консольные утилиты, которые показывают состояние системы и процессов запущенных в ней.
Утилита ps — это не интерактивная консольная утилита, которая умеет показывать множество атрибутов различных процессов, запущенных в системе.
Если тебе понравилась эта статья, подпишись на мой канал в VK.