Процессы в Linux
Table of Contents
1 Процесс
Обычно программой называют совокупность файлов, будь то набор исходных текстов, объектных фалов или собственно исполняемый файл. Для того чтобы программа могла быть запущена на выполнение, операционная система сначала должна создать окружение или среду выполнения задачи, куда относятся ресурсы памяти, возможность доступа к устройствам ввода/вывода и различным системным ресурсам, включая услуги ядра.
- Процесс является тлько «мёртвой» статической оболочкой, хранящей учётные данные и обеспечивающей окружение динамического исполнения потока, даже если это единственный (главный) исполняемый поток приложения (процесса), как это принято в терминологии, не имеющей отношения к потоковым понятиям.
- Любые взаимодействия, синхронизация, диспетчирезация и другие механизмы имеют смысл только применительно к потокам, даже если это потоки, локализованные в рамках различных процессов. Здесь возникает термин IPC — средство взаимодействия процессов. Для однопотоковых приложений этот терминологический нюанс не вносит ровно никакого различия, но при переходе к многопотоковым приложениям мы должны рассуждать в терминах именно взаимодействующих потоков, локализованных внутри процессов (одного или различных)
- В системах с аппаратной трансляцией адресов памяти (MMU — Memory Management Unit) процесс создаёт для своих потоков дополнительные «границы существования» — защищённое адресное пространство. Большинство сложностей, описываемых в литературе в связи с использованием IPC, обусловлено необходимостью взаимодействующих потоков преодолевать адресные барьеры, устанавливаемые процессами для каждого из них.
1.1 Атрибуты процессов
- PID
- идентификатор процесса, присваиваемый процессу при создании, например вызовом fork(). PID позволяет системе однозначно идентифицировать каждый процесс. При создании процесса ему присваивается первый свободный идентификатор. Присвоение происходит по возрастающей до тех пор пока не кончатся доступные значения PID. Тогда следующий процесс получает минимальный свободный PID, и весь цикл повторяется снова. Процесс, загружавший ОС, является родительским для всех процессов в системе и его PID = 1, обычно называется init, запускается ядром ОС по окончании процедуры bootstrap. Процесс с PID = 0 это обычно процесс scheduler также называемый swapper. Процесс init никогда не умирает в процессе работы ОС. Это обычный пользовательский процесс (в отличие от процесса swapper, работающего в ядре), хотя и запущен с привелегиями суперпользователя.
pid_t p = getpid(); printf("current pid: %zu", p);
current pid: 25401
- PPID
- PID процесса, породившего данный процесс.
pid_t pp = getppid(); printf("current ppid: %zu", pp);
current ppid: 10153
- TTY
- терминальная линия: терминал или псевдотерминал, ассоциированный с процессом. Если процесс становится процессом-демоном, то он отсоединяется от своей терминальной линии и не имеет ассоциированной терминальной линии.
- RID
- реальный индентификатор пользователя.
uid_t u = getuid(); printf("current uid: %zu", u);
current uid: 1000
- EUID
- эффективный идентификатор пользователя. Эффективный идентификатор служит для определения прав доступа процесса к системным ресурсам. Обычно RID и EUID совпадают, но установка SUID флага для исполняемого файла процесса позволяет расширить полномочия процесса.
uid_t eu = geteuid(); printf("current effective uid: %zu", eu);
current effective uid: 1000
- RGID
- реальный идентификатор группы.
gid_t g = getgid(); printf("current gid: %zu", g);
current gid: 1000
- EGID
- эффективный идентификатор группы. EGID не совпадает с RGID в случае когда установлен флаг SGID.
gid_t eg = getegid(); printf("current effective gid: %zu", eg);
current effective gid: 1000
Часто в качестве атрибутов процесса называют и приоритет выполнения. Однако приоритет является атрибутом не процесса, а потока, но если поток единственный (главный, порождённый функцией main()), его приоритет и есть то, что понимается под «приоритетом процесса»