Процессы в Unix

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

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

Для оперативного хранения рабочих данных существует динамическая область памяти (куча(heap)). Эта память выделяется динамически и использование ее от процесса к процессу меняется. С помощью кучи программист может предоставить процессу дополнительную память.

Автоматически, при запуске программы, переменные размещаются в стeке (стек служит хранилищем для временного хранения переменных и адресов возврата из процедур). Обычно при выполнении или в режиме ожидания выполнения процессы находятся в оперативной памяти компьютера. Довольно большая ее часть резервируется ядром операционной системы, и только к оставшейся ее чати могут получить доступ пользователи. Одновременно в оперативной памяти может находится несколько процессов. Память, используемая процессором, разбивается на сегменты, называемые стpаницами (page). Каждая страница имеет определенный размер, который фиксирует операционная система в зависимости от типа вашего компьютера. Если все страницы используются и возникает потребность в новой странице, то та страница которая используется меньше остальных помещается в область подкачки (swap area), а на ее месте создается новая. Но если область подкачки не была определена, то с помощью специальных комманд можно разместить область подкачки в файле. Но есть такие страницы которые всегда должны находится в оперативной памяти, которые называются невытесняемыми (nonpreemptable pages). Обычно такие страницы используются ядром, либо программами подкачки. Главная особенность в постраничном использовании памяти заключается в том, что процесс может использовать больше памяти, чем есть на самом деле.
Процессы могут функционировать в двух режимах: системном и пользовательском. Работа в ситемном режиме означает выполнение процессом системных вызовов. Он наиболее важен, так как в нем выполняется обработка прерываний, вызванных внешними сигналами и системными вызовами, а также управлением доступом к диску, распределение дополнительной динамической памяти и других ресурсов системы. Процесс функционирует в пользовательском режиме, когда выполняется код, заданный пользователем.

Для каждого процесса создается свой блок управления, который помещается в системную таблицу процессов, находящихся в ядре. Эта таблица представляет собой массив структур блоков управления процессами. В каждом блоке содержатся данные:
- слово состояния процесса
- приоритет
- величина кванта времени, выделенного системным планировщиком
- степень испльзования системным процессором
- признак диспетчеризации
- идентификатор пользователя, которому принадлежит процесс
- эффективный идентификатор пользователя
- реальный и эффективный идентификаторы группы
- группа процесса
- идентификатор процесса и идентификатор родительского процесса
- размер образа, размещаемого в облати подкачки
- размер сегментов кода и данных
- массив сигналов, ожидающих обработки.
Чтобы система функционировала должным образом, ядру необходимо отслеживать все эти данные.

Создание и завершение процесса
Процесс порождается с помощью системного вызова fork(). При этом вызове происходит проверка на наличие свободной памяти, доступной для размещения нового процесса. Если требуемая память доступна, то создается процесс-потомок текущего процесса, представляющий собой точную копию вызывающего процесса. При этом в таблице процессов для нового процесса строится соответствующая структура. Новая структура создается также в таблице пользователя. При этом все ее переменные инициализирутся нулями. Этому процессу присваивается новый уникальный идентификатор, а идентификатор родительского процесса запоминается в блоке управления процессом.

Для завершения процесса используется системный вызов exit(), при котором освобождаются все используемые ресурсы, такие как память и структуры таблиц ядра. Кроме того, завершаются и процесс-потомки, порожденные данным процессом. Затем из памяти удаляются сегменты кода и данных, а сам процесс переходит в состояние зомби (для таких процессов в таблицах ядра сохраняются некоторые записи, но в конечном счете его судьбу решает его родительский процесс). И наконец родительский процесс должен очистить все ресурсы, занимаемые дочерними процессами.

Взаимодействие процессов
Самым распространенным средством взaимодействия процессов являются сокеты (sockets). Программы подключаются к сокету и выдают запрос на привязку к нужному адресу. Затем данные передаются от одного сокета к другому в соответствии с указанным адресом.

Сигнал информирует другой процесс о возниконовении определенных условий внутри текущего процесса, требующих реакции текущего процесса. Многие программы обработки сигналов для анализа возникшей проблемы выводят дамп памяти.

Каналы реализованы в двух классах. Первый из них создается с помощью системного вызова pipe(). При этом для обмена информацией между процессами инициализируется специальная структура в ядре. Вызывающему процессу два дескриптора файла, один-для чтения, а другой для записи информации. Затем, когда процесс пораждает новый процесс, между двумя процессами открывается коммуникационный канал. Другим типом каналов являются именованные каналы. При их использовании с управляющей структурой в ядре связывается специальный каталог, через который два автономных процесса могут обмениваться данными. При этом, каждый процесс должен открыть канал в виде обычных файлов (один - для чтения, другой - для записи). Затем операции ввода-ввывода выполняются обычным образом.

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

Семафоры представляют собой средство передачи флагов от одного процесса к другому. "Подняв" семафор, процесс может сообщить, что он находится в определенном состоянии. Любой другой процесс в системе может отыскать этот флаг и выполнить необходимые действия.

Совместно используемая память позволяет процессам получить доступ к одной и той же области физической памяти.