Реализация процессов в ос unix

Процесс ОС Unix

Механизм управления и взаимодействия процессов в ОС Unix послужил во многом основой для развития операционных систем в целом, и логического блока управления процессами в частности. Во многом организация управления процессами в ОС Unix является эталонной, рассмотрим ее теперь более детально.

С точки зрения понимания термина процесса в ОС Unix данное понятие можно определить двояко. В первом случае процесс можно определить как объект, зарегистрированный в таблице процессов. Таблица процессов является одной из специальных системных таблиц, которая, очевидно, является программной таблицей. Второе определение объявляет процессом объект, порожденный системным вызовом fork(). Оба определения являются корректными и равносильными (если учесть, что в системе существуют два особых процесса с нулевым и первым номерами, и об их особенностях речь пойдет ниже).

Остановимся сначала на первой трактовке процесса. В операционной системе имеется таблица процессов, размер которой является параметром настройки ОС, и, соответственно, количество процессов в системе является системным ресурсом. Таблица устроена позиционным образом, а это означает, что именование процесса осуществляется посредством номера записи таблицы, соответствующей данному процессу (нумерация строится от нуля до некоторого фиксированного значения). Этот номер записи называется идентификатором процесса (PID — Process Identifier). Как только что отмечалось, две первые записи таблицы предопределены и используются для системных нужд. Соответственно, каждая запись таблицы (Рис. 74) имеет ссылку на контекст процесса, который структурно состоит из пользовательской, системной и аппаратной составляющих.

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

Реализация процессов в ос unix

Рис. 74. Таблица процессов в ОС Unix.

В ОС Unix реализована такая возможность, как разделение сегмента кода (Рис. 75). Допустим, в системе работает несколько (пускай, 100) пользователей, каждый из которых помимо прочего работает с одним и тем же текстовым редактором. Таким образом, в системе обрабатываются 100 копий текстового редактора. Ставится вопрос о необходимости держать в ОЗУ все сегменты кода для этих 100 процессов. Для оптимизации подобных ситуаций в ОС Unix используется указанный механизм разделения сегмента кода. Тогда каждый обрабатываемый в системе процесс текстового редактора в пользовательской составляющей хранит ссылку на единственную копию сегмента кода редактора, а сегмент данных у каждого из процессов оказывается своим. Соответственно, в приведенном примере в памяти будут находиться один сегмент кода и 100 сегментов данных. Но рассмотренный механизм может иметь место в ОС только в том случае, когда сегмент кода нельзя изменить: он закрыт на запись.

Реализация процессов в ос unix

Рис. 75. Разделение сегмента кода.

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

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

Одними из таких параметров являются реальный и эффективный идентификаторы пользователя-владельца. В ОС Unix формированием процесса считается запуск исполняемого файла на выполнение. Исполняемым считается файл, имеющий установленный соответствующий бит исполнения в правах доступа к нему, при этом файл может содержать либо исполняемый код, либо набор команд для командного интерпретатора. Каждый пользователь системы имеет свой идентификатор (UID — User ID). Каждый файл имеет своего владельца, т.е. для каждого файла определен UID пользователя-владельца. В системе имеется возможность разрешать запуск файлов, которые не принадлежат конкретному пользователю. Большинство команд ОС Unix представляют собой исполняемые файлы, принадлежащие системному администратору (суперпользователю). Таким образом, при запуске файла определены фактически два пользователя: пользователь-владелец файла и пользователь, запустивший файл (т.е. пользователь-владелец процесса). И эта информация хранится в контексте процесса, как реальный идентификатор — идентификатор владельца процесса, и эффективный идентификатор — идентификатор владельца файла. А дальше возможно следующее: можно подменить права процесса по доступу к файлу с реального идентификатора на эффективный идентификатор. Соответственно, если пользователь системы хочет изменить свой пароль доступа к системе, хранящийся в файле, который принадлежит лишь суперпользователю и только им может модифицироваться, то этот пользователь запускает процесс passwd, у которого эффективный идентификатор пользователя — это идентификатор суперпользователя (UID = 0), а реальным идентификатором будет UID данного пользователя. И в этом случае права рядового пользователя заменятся на права администратора, поэтому пользователь сможет сохранить новый пароль в системной таблице (в соответствующем файле).

Итак, следуя второй трактовке, процессом называется объект, порожденный системным вызовом fork(). Выше уже упоминалось определение системного вызова, повторим его. Под системным вызовом понимается средство ОС, предоставляемое пользователям, а точнее, процессам, посредством которого процессы могут обращаться к ядру операционной системы за выполнением тех или иных функций. При этом выполнение системных вызовов происходит в привилегированном режиме (поскольку непосредственную обработку системных вызовов производит ядро), даже если сам процесс выполняется в пользовательском режиме. Что касается реализации системных вызовов, то в одних случаях системный вызов считается специфическим прерыванием, в других случаях — как команда обращения к операционной системе.

03 — Программирование Linux. Процессы и потоки


Похожие статьи.

Понравилась статья? Поделиться с друзьями: