Лекции по операционным системам (1114687), страница 16
Текст из файла (страница 16)
-
Модель пакетной мультипроцессной системы. 0 — поступление процесса в очередь на начало обработки ЦП (процесс попадает в БВП). 1 — начало обработки процесса на ЦП (из БВП в БОП). 2 — процесс прекращает обработку ЦП по причине ожидания операции ввода-вывода, поступает в очередь завершения операции обмена (БОП). 3 — операция обмена завершена, и процесс поступает в очередь ожидания продолжения выполнения ЦП (БОП). 4 — выбирается процесс для выполнения на ЦП. 5 — завершение выполнения процесса, освобождение системных ресурсов.
Произведя в рассмотренной модели пакетной мультипроцессной системы небольшие изменения, можно получить модель операционной системы с разделением времени (Рис. 71.). Структурно достаточно добавить возможность перехода из состояния обработки центральным процессором в очередь готовых на выполнение процессов. Т.е. система имеет возможность прервать выполнение текущего процесса и поместить его в указанную очередь. Но такая модель не предполагает свопинга, или механизма откачки процесса во внешнюю память. В принципе, такую возможность можно также добавить в модель системы (Рис. 72.), тогда появляется еще одно состояние, характеризующее процесс, как откачанный во внешнюю память. Заметим, что в новое состояние могут переходить процессы лишь из очереди готовых на выполнение процессов, а процессы, ожидающие окончания ввода-вывода, свопироваться не могут, иначе в системе будут «зависать» заказы на обмен.
-
Модель ОС с разделением времени. 6 — процесс прекращает обработку ЦП, но в любой момент может быть продолжен (истек квант времени ЦП, выделенный процессу). Поступает в очередь процессов, ожидающих продолжения выполнения центральным процессором (БОП).
-
Модель ОС с разделением времени (модификация). Заблокированный процесс может быть откачан (свопирован) на внешний носитель, а на освободившееся место может быть подкачен процесс с внешнего носителя, который был откачен ранее, либо взят новый.
2.1.2Типы процессов
Рассматривая процесс в той или иной операционной системе, можно обнаружить, что встречается деление процессов на две категории: т.н. полновесные процессы и легковесные процессы, или нити.
Полновесные процессы (иногда их называют просто процессы) — это те процессы, машинный код которых обладает эксклюзивными правами на владение оперативной памятью (т.е. это традиционная однопроцессная программа).
Альтернативой являются т.н. легковесные процессы, известные также как нити, — это процессы, которые могут работать совместно с другими процессами на общем пространстве оперативной памяти. Обычно легковесные процессы реализуются внутри полновесного процесса.
-
Типы процессов: однонитевая (а) и многонитевая (б) организации.
Тогда традиционную однопроцессную программу, которую мы отнесли к полновесным процессам, можно теперь переопределить как однонитевой процесс, т.е. этому процессу эксклюзивно выделена память, и внутри существует один набор команд, который владеет и работает в этой защищенной области памяти. Многонитевая организация подразумевает выделение процессу защищенной области памяти, но внутри эта область доступна двум и более нитям.
Организуя многонитевые процессы, обычно преследуются следующие цели. Во-первых, это снижение накладных расходов. Как отмечалось выше, смена контекста полновесных процессов является трудоемкой операцией. В то же время, смена контекста нитей в рамках одного процесса является более простой задачей, поскольку не требуется полного переконфигурирования системы.
Также отметим, что многонитевые процессы хорошо ложатся на современные многопроцессорные системы (например, SMP-системы), т.е. в некоторых случаях при такой организации повышается эффективность системы.
Кроме того, механизм нитевой организации позволяет осуществлять взаимодействие нитей в рамках одного процесса, причем адресное пространство, посредством которого они взаимодействуют, остается защищенным от других процессов в системе.
Соответственно, перед операционной системой помимо управления полновесными процессами, планирования и выделения им ресурсов возникает задача управления нитями.
Тогда определение процесса можно расширить. Процесс — это совокупность исполняемого кода с собственным адресным пространством, представляющее собой множество виртуальных адресов, которые может использовать процесс, и назначенными ему ресурсами системы, и которая содержит хотя бы одну нить.
В заключение отметим, что многие современные операционные системы (как семейства Unix, так и Windows-системы, и др.) обеспечивают работу с нитями.
2.1.3Контекст процесса
Говоря о различных механизмах, происходящих в системе, часто затрагивался термин контекст процесса. Под контекстом процесса мы будем понимать совокупность данных, характеризующих актуальное состояние процесса. Обычно контекст процесса состоит из нескольких компонент:
-
пользовательская составляющая — это совокупность машинных команд и данных, которые характеризуют выполнение данного процесса;
-
системная составляющая, которая содержит в себе информацию об именовании, правах процесса, т.е. различного рода учетная системная информация, а также содержит информацию о состоянии процесса в точке останова (содержимое регистров, настройки процесса и пр.). Соответственно, о последнем имеет смысл говорить лишь тогда, когда процесс откачан. Во время исполнения процесса обычно говорят об аппаратной составляющей контекста (т.е это актуальное состояние регистров, актуальные настройки процесса и пр.). Таким образом, когда процесс обрабатывается на процессоре, то актуальна аппаратная составляющая, когда процесс отложен — актуальна системная составляющая.
2.2Реализация процессов в ОС Unix
2.2.1Процесс ОС Unix
Механизм управления и взаимодействия процессов в ОС Unix послужил во многом основой для развития операционных систем в целом, и логического блока управления процессами в частности. Во многом организация управления процессами в ОС Unix является эталонной, рассмотрим ее теперь более детально.
С точки зрения понимания термина процесса в ОС Unix данное понятие можно определить двояко. В первом случае процесс можно определить как объект, зарегистрированный в таблице процессов. Таблица процессов является одной из специальных системных таблиц, которая, очевидно, является программной таблицей. Второе определение объявляет процессом объект, порожденный системным вызовом fork(). Оба определения являются корректными и равносильными (если учесть, что в системе существуют два особых процесса с нулевым и первым номерами, и об их особенностях речь пойдет ниже).
Остановимся сначала на первой трактовке процесса. В операционной системе имеется таблица процессов, размер которой является параметром настройки ОС, и, соответственно, количество процессов в системе является системным ресурсом. Таблица устроена позиционным образом, а это означает, что именование процесса осуществляется посредством номера записи таблицы, соответствующей данному процессу (нумерация строится от нуля до некоторого фиксированного значения). Этот номер записи называется идентификатором процесса (PID — Process Identifier). Как только что отмечалось, две первые записи таблицы предопределены и используются для системных нужд. Соответственно, каждая запись таблицы (Рис. 74.) имеет ссылку на контекст процесса, который структурно состоит из пользовательской, системной и аппаратной составляющих.
Пользовательская составляющая — это тело процесса. В нее входит сегмент кода, который содержит машинные команды и неизменяемые константы. Сегмент кода — это обычно не изменяемая программным способом часть тела процесса. Также в пользовательскую составляющую входит сегмент данных, в который входит область статических данных процесса (в т.ч. статические переменные), область разделяемой памяти (т.е. область памяти, которая может принадлежать двум и более процессам одновременно), а также область стека. На стеке в системе реализуется передача фактических параметров в функциях, реализуются автоматические и регистровые переменные, а также в этой области организуется динамическая память (т.н. куча).
-
Таблица процессов в ОС Unix.
В ОС Unix реализована такая возможность, как разделение сегмента кода (Рис. 75.). Допустим, в системе работает несколько (пускай, 100) пользователей, каждый из которых помимо прочего работает с одним и тем же текстовым редактором. Таким образом, в системе обрабатываются 100 копий текстового редактора. Ставится вопрос о необходимости держать в ОЗУ все сегменты кода для этих 100 процессов. Для оптимизации подобных ситуаций в ОС Unix используется указанный механизм разделения сегмента кода. Тогда каждый обрабатываемый в системе процесс текстового редактора в пользовательской составляющей хранит ссылку на единственную копию сегмента кода редактора, а сегмент данных у каждого из процессов оказывается своим. Соответственно, в приведенном примере в памяти будут находиться один сегмент кода и 100 сегментов данных. Но рассмотренный механизм может иметь место в ОС только в том случае, когда сегмент кода нельзя изменить: он закрыт на запись.
-
Разделение сегмента кода.
Аппаратная составляющая включает в себя все регистры, аппаратные таблицы процессора и пр., характеризующие актуальное состояние процесса в момент его выполнения на процессоре.
Системная составляющая содержит системную информацию об идентификации процесса (т.е. идентификация пользователя, сформировавшего процесс), системная информация об открытых и используемых в процессе файлах и пр., а также сохраненные значения аппаратной составляющей. Итак, системная составляющая хранит множество параметров, рассмотрим некоторые из них.
Одними из таких параметров являются реальный и эффективный идентификаторы пользователя-владельца. В ОС Unix формированием процесса считается запуск исполняемого файла на выполнение. Исполняемым считается файл, имеющий установленный соответствующий бит исполнения в правах доступа к нему, при этом файл может содержать либо исполняемый код, либо набор команд для командного интерпретатора. Каждый пользователь системы имеет свой идентификатор (UID — User ID). Каждый файл имеет своего владельца, т.е. для каждого файла определен UID пользователя-владельца. В системе имеется возможность разрешать запуск файлов, которые не принадлежат конкретному пользователю. Большинство команд ОС Unix представляют собой исполняемые файлы, принадлежащие системному администратору (суперпользователю). Таким образом, при запуске файла определены фактически два пользователя: пользователь-владелец файла и пользователь, запустивший файл (т.е. пользователь-владелец процесса). И эта информация хранится в контексте процесса, как реальный идентификатор — идентификатор владельца процесса, и эффективный идентификатор — идентификатор владельца файла. А дальше возможно следующее: можно подменить права процесса по доступу к файлу с реального идентификатора на эффективный идентификатор. Соответственно, если пользователь системы хочет изменить свой пароль доступа к системе, хранящийся в файле, который принадлежит лишь суперпользователю и только им может модифицироваться, то этот пользователь запускает процесс passwd, у которого эффективный идентификатор пользователя — это идентификатор суперпользователя (UID = 0), а реальным идентификатором будет UID данного пользователя. И в этом случае права рядового пользователя заменятся на права администратора, поэтому пользователь сможет сохранить новый пароль в системной таблице (в соответствующем файле).
Итак, следуя второй трактовке, процессом называется объект, порожденный системным вызовом fork(). Выше уже упоминалось определение системного вызова, повторим его. Под системным вызовом понимается средство ОС, предоставляемое пользователям, а точнее, процессам, посредством которого процессы могут обращаться к ядру операционной системы за выполнением тех или иных функций. При этом выполнение системных вызовов происходит в привилегированном режиме (поскольку непосредственную обработку системных вызовов производит ядро), даже если сам процесс выполняется в пользовательском режиме. Что касается реализации системных вызовов, то в одних случаях системный вызов считается специфическим прерыванием, в других случаях — как команда обращения к операционной системе.
2.2.2Базовые средства управления процессами в ОС Unix
Рассмотрим теперь, что происходит при обращении к системному вызову fork(). При обращении процесса к данному системному вызову операционная система создает копию текущего процесса, т.е. появляется еще один процесс, тело которого полностью идентично исходному процессу. Это означает, что система заносит в таблицу процессов новую запись, тем самым новый процесс получает уникальный идентификатор, а также в системе создается контекст для дочернего процесса.
Новый процесс наследует почти все атрибуты исходного родительского процесса, за исключением идентификационной информации (т.е. у дочернего процесса, в частности, свой идентификатор PID и иной идентификатор родительского процесса). Среди прочего дочерний процесс наследует открытые отцовским процессом файлы. На это свойство в ОС Unix опираются многие механизмы. Хотя необходимо отметить, что наследуются необязательно все открытые файлы: если некоторый файл открывался в специальном режиме, то при формировании дочернего процесса этот файл для него будет автоматически закрыт.
#include <sys/types.h>
#include <unistd.h>