Операционные системы. Управление ресурсами

       

Архитектурные концепции операционных систем


ОС является сложным программным изделием, поэтому при ее проектировании невозможно пренебрегать вопросами структурирования, что подчас допустимо при разработке небольших программ. Все архитектуры ОС в том или ином варианте используют модульно-интерфейсные методы структурирования [6, 10]. ОС представляется состоящей из ряда модулей (планирование процессов, управление памятью, подсистема ввода-вывода и т.д.), для каждого из которых определены спецификации функционирования и интерфейсы. ОС, однако, различаются по способам оформления модулей и связей между ними. Модульный состав и организация межмодульного взаимодействия и составляют архитектуру ОС.

Первой из четко сформулированных архитектурных концепций ОС была иерархия абстрактных машин, предложенная Дейкстрой в 1968 году для ОС THE (описание можно найти в [20]). Иерархия абстрактных машин в этой системе показана на рисунке 1.6. Самый нижний (нулевой) уровень иерархии составляет реальная машина с ее интерфейсом оборудования. Нижний слой программного обеспечения составляет первый уровень. Совместно с аппаратными средствами он представляет некоторую абстрактную машину со своим, более высокоуровневым интерфейсом оборудования. На основе этого интерфейса строится абстрактная машина второго уровня и т.д. Последовательным наращиванием слоев программного обеспечения интерфейс абстрактной машины доводится до уровня интерфейса процессов.


Рис.1.6. Иерархия абстрактных машин в системе THE

Реализация архитектуры абстрактных машин сопряжена со значительными трудностями, связанными с правильным выбором уровней и их иерархическим упорядочением. Система THE представляет только один из возможных вариантов, применимый далеко не во всех случаях. Успешность решения этой проблемы во многом зависит от выбранного метода проектирования. В первоисточнике реализация иерархии абстрактных машин производилась методом "снизу-вверх". Другие авторы (например, [11]) настаивают на реализации методом "сверху вниз". По-видимому, наиболее продуктивным является комбинированный метод, пример применения которого приведен в [10]: спецификации уровней разрабатываются "сверху вниз", а реализация ведется "снизу вверх".
У процесса создается иллюзия, что в его полном распоряжении находится реальная вычислительная система (с той, однако, поправкой, что временные соотношения выполнения некоторых команд не выдерживаются). А если так, то процесс в свою очередь может быть ОС, так называемой гостевой (guest) ОС, которая в полном объеме управляет выделенным ей подмножеством ресурсов.

Другой вариант концепции виртуальной машины представляет интерфейс нижнего уровня системного программного обеспечения как полнофункциональный набор команд некоторой воображаемой машины. Все вышележащие уровни программного обеспечения пишутся в этом наборе команд (или компилируются в него). Программный модуль, готовый для выполнения, представляет собой двоичный код программы в командах виртуальной машины. Перевод команд виртуальной машины в команды конкретной аппаратной платформы выполняется нижележащим уровнем программного обеспечения в режиме перекомпиляции (например, AS/400 [18]) или интерпретации (например, технология Java [29]), компилятор или интерпретатор входит в состав нижнего уровня. Использование промежуточного кода в командах виртуальной машины обеспечивает переносимость программного обеспечения на другие платформы, так как все, в том числе и системное, программное обеспечения, лежащее выше уровня интерфейса виртуальной машины, является платформенно-независимым и при переносе не требует даже перекомпиляции.

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


Минимальный набор функций микроядра включает в себя:



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


Архитектурная концепция микроядра также обеспечивает переносимость системного программного обеспечения верхнего уровня (хотя и с необходимостью его перекомпиляции).

Набор преимуществ, обеспечиваемых микроядром, очень велик, и в разных системах это понятие трактуется по-разному - в зависимости от того, какие требования к системе являются доминирующими. Так, описанный выше подход минимизации кода, выполняемого в режиме ядра, и повышения эффективности в полной мере реализован, например, в ОС QNX [32]. В Windows NT/200 [16] микроядром называют часть, обеспечивающую независимость от внешнего оборудования и ряд функций режима ядра, но одним микроядром эти функции не исчерпываются. В AS/400[18] часть кода, лежащую ниже интерфейса виртуальной машины тоже иногда называют микроядром, хотя для программного обеспечения, состоящего из более, чем 1 млн. строк кода на языке C++, префикс "микро" вряд ли уместен.

Еще одной тенденцией в развитии ОС является объектно-ориентированный подход к их проектированию. Как известно, основными свойствами объектно-ориентированного программирования являются инкапсуляция, полиморфизм и наследование. Из указанных свойств в объектно-ориентированных ОС в полной мере реализуется прежде всего первое. Ресурсы в таких системах представляются в виде экземпляров тех или иных классов, внутренняя структура класса недоступна вне класса, но для класса определены методы работы с ним.




Наряду с повышением степени интеграции тех базовых элементов, из которых строится ОС, инкапсуляция обеспечивает также защиту ресурсов и возможность менять в новых версиях ОС или при переносе на новую платформу структуру системных объектов без изменения тех программ, которые оперируют объектами. Для каждого типа объектов определен набор допустимых операций над ним. Свойство полиморфизма состоит в том, что для различных системных классов могут быть определены одноименные операции, выполнение которых для разных классов будет включать в себя как общие, так и специфические для каждого класса действия. Важнейшей из таких операций является получение доступа к объекту, отдельно рассматриваемое нами в главе 10. Свойство наследования реализуется в объектно-ориентированных ОС лишь отчасти, в связи с чем некоторые авторы (например, [18]) считают, что правильнее называть эти ОС объектно-базированными. В системах с иерархической структурой (Windows NT, AS/400) объекты более высокого уровня могут включать в себя объекты нижних уровней, однако, производные классы не наследуют методы базовых и, следовательно, их экземпляры не могут обрабатываться как экземпляры базового класса. Нельзя, однако, говорить об этом ограничении, как о недостатке, так как оно диктуется концепцией иерархической архитектуры: каждый уровень должен оперировать только объектами своего уровня.

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

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


Архитектура процессов ядра может совмещаться с архитектурой иерархии абстрактных машин: каждый уровень иерархии обеспечивается своим набором процессов ядра. Промежуточным случаем является подход, характерный, например, для ОС Unix: обращение процесса к ОС вызывает переключение контекста на ядро, но не переключение процессов, то есть, модули ядра выполняются в контексте вызвавшего их процесса. В тех ОС, в которых отношения между процессами строятся по схеме "предок-потомок", иерархия может непосредственно отображаться в "родственных отношениях" процессов. Что касается процедурной архитектуры, то такие отношения в ней естественным образом отображаются на вложенности вызовов процедур.

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

Еще один важный вопрос - организация взаимодействия между модулями и здесь можно выделить две модели [14]: интерфейс процедур и интерфейс сообщений. Интерфейс процедур подразумевает непосредственное обращение вызывающего модуля к вызываемому, подобное обращению к подпрограмме в языках программирования. Обращение может быть либо действительно обращением к процедуре (команда CALL), либо сводиться к прерыванию и переключению процессов. Модель интерфейса процедур синхронная, то есть, как и при вызове подпрограммы, выполнение вызывающего модуля приостанавливается до получения результата вызова.


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

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




Содержание раздела