Процессы - общие сведения
Процесс в Unix/Linux представляет собой единицу работы вычислительной системы, которой операционная система выделяет ресурсы. С некоторой степенью приближения можно определить процесс как выполняющуюся программу. Каждый процесс в системе имеет свой уникальный идентификатор процесса (PID), представляемый целым числом.
Каждому процессу в операционной системе соответствует запись в таблице
процессов и адресное пространство процесса. Запись в таблице процессов (и ее
расширение в адресном пространстве процесса) содержит управляющую информацию о
ресурсах, выделенных процессу, и о состоянии процесса. Адресное пространство
содержит коды и данные процесса.
Процесс может порождать другой процесс. Порождение нового процесса в Linux (Unix)
реализовано копированием записи таблицы процессов, таким образом, что
процесс-потомок в момент своего порождения представляет собой точную копию
процесса-предка. Это называется создание процесса. Процесс-предок и процесс-потомок далее выполняются
параллельно, но процесс-предок может и ожидать завершения процесса-потомка.
Процессы в Unix/Linux выполняются в режиме разделения времени, это означает,
что время центрального процессора равномерно (с учетом приоритетов)
распределяется между всеми готовыми к выполнению процессами. Даже если процесс
не переходит в состояние ожидания (например, ожидания выполнения операции
ввода-вывода) по своей инициативе, по истечении выделенного процессу кванта
времени выполнение процесса будет прервано операционной системой, и процессор
будет отдан более приоритетному процессу. Unix/Linux применяет динамическое
перевычисление приоритетов, приоритет выполняющегося процесса понижается, а
приоритеты ожидающих процессов повышаются.
Порождение процессов в Linux
Новый процесс порождается системным вызовом fork,
который создает дочерний процесс - копию родительского. В дочернем процессе
выполняется та же программа, что и в родительском, и когда дочерний процесс
начинает выполняться, он выполняется с точки возврата из системного вызова
fork. Системный вызов fork
возвращает родительскому процессу PID дочернего процесса, а дочернему процессу
- 0. По коду возврата вызова fork дочерний
процесс может "осознать" себя как дочерний. Свой PID процесс может получить при
помощи системного вызова getpid,
а PID родительского процесса - при помощи системного вызова
getppid. Если требуется, чтобы в дочернем процессе
выполнялась программа, отличная от программы родительского процесса, процесс
может сменить выполняемую в нем программу при помощи одного из системных
вызовов семейства exec. Все вызовы
этого семейства загружают для выполнения в процессе программу из заданного в
вызове файла и отличаются друг от друга способом передачи параметров этой
программе. Таким образом, наиболее распространенный контекст применения
системного вызова fork выглядит
примерно так:
/* порождение дочернего процесса и запоминание его PID */
if (!(ch_pid=fork())
/* загрузка другой программы в дочернем процессе */
exec(программа);
else
продолжение родительского процесса