Многоуровневые системы

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

Первой системой, построенной таким образом, была простая мультипрограммная пакетная система T.H.E., которую построил Дейкстра и его студенты в 1968 году. Одна из наиболее общих характеристик среды выполнения - четкое распределение ее функций по уровням.

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

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

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

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

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

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

В многопроцессорной системе необходимо иметь унифицированный механизм выполнения P- и V-операций. Его отсутствие может создать следующую ситуацию: Пр1, обратившись к семафору, убеждается в том, что он открыт, и пытается записать 0 в сигнальный разряд, но еще до того, как сигнал успел измениться, к семафору обращается Пр2, и, найдя семафор открытым, пытается захватить соответствующий ресурс. Для обработки таких ситуаций существуют специальные алгоритмы, но в большинстве мультипроцессорных систем обращение к семафору и изменение его состояния осуществляется с помощью единого механизма, реализуемого одной непрерывной командой. Процессор, обращаясь к сигнальному разряду семафора, к которому до этого с командой проверить и установить (test-and-set или compare-and-swap) уже обратился другой процессор, получает доступ к семафору только по завершении выполнения над ним предшествующей единой операции. Такой способ поддержки целостности P- и V-операций реализуется аппаратно.

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

Дейкстра предложил следующую структуру среды выполнения:

Система имела 6 уровней. Уровень 0 занимался распределением времени процессора, переключая процессы по прерыванию или по истечении времени. Уровень 1 управлял памятью - распределял оперативную память и пространство на магнитном барабане для тех частей процессов (страниц), для которых не было места в ОП, то есть слой 1 выполнял функции виртуальной памяти. Слой 2 управлял связью между консолью оператора и процессами. С помощью этого уровня каждый процесс имел свою собственную консоль оператора. Уровень 3 управлял устройствами ввода-вывода и буферизовал потоки информации к ним и от них. С помощью уровня 3 каждый процесс вместо того, чтобы работать с конкретными устройствами, с их разнообразными особенностями, обращался к абстрактным устройствам ввода-вывода, обладающим удобными для пользователя характеристиками. На уровне 4 работали пользовательские программы, которым не надо было заботиться ни о процессах, ни о памяти, ни о консоли, ни об управлении устройствами ввода-вывода. Процесс системного оператора размещался на уровне 5.

Уровень 5 Программа Системный оператор  
Уровень 4 Программа управления заданиями 1.Прикладные процессы 2.Интерпретация языка программирования
Уровень 3 Программа управления устройствами 1.Установление соответствия между логическими и физическими устройствами 2.Буферизация
Уровень 2 Программа связи с оператором 1.Поддержка связи с оператором 2.Управление системной консолью
Уровень 1 Страничный супервизор 1.Управление памятью 2.Поддержка виртуальной памяти
Уровень 0 Ядро ОС 1.Управление выполнением процесса 2.Обеспечение синхронизации

Рис.3.3.1. Уровни ОС T.H.E. (Дейкстра)

Функции управления памятью включаются в систему в следующих случаях:

1. Пользовательская (или любая другая программа) для запросов дополнительных областей памяти применяет специальные макрокоманды среды выполнения.

2. Пользовательская (или любая другая) программа при необходимости получает дополнительное пространство посредством механизма "виртуальной" памяти, проецирующего ее на "реальную" память.

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

Общие принципы иерархического построения систем:

1. Функции более низких уровней для более высоких неотличимы от аппаратных и обладают четкими интерфейсами.

2. Функции более высокого уровня могут обращаться только к своим нижним соседям по иерархии и не имеют информации о более глубокой структуре системы.

3. Каждый уровень работает только со своими структурами данных.

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

На современном этапе предлагают различные варианты иерархии. Например, систему можно построить так, что на нижнем уровне окажется лишь монитор (диспетчер + механизм обработки прерываний). При этом функции синхронизации переместятся на более высокий уровень и будут применяться для более тонкой синхронизации, чем использование P- и V-операций. В другом варианте на нижний уровень помещается только механизм управления УВВ. Это выгодно, если применяемая аппаратура требует подготовки достаточно объемных программ для выполнения элементарных аппаратных функций. Этот же способ годится для систем реального времени, где диспетчер представляет собой не самый удобный набор базисных функций. Мэдник и Донован (Madnick and Donovan) считают целесообразным обобщить уровень 3 иерархической структуры и возложить на него ответственность за управление процессами. На этом уровне создаются и уничтожаются управляющие блоки, содержащие информацию о выполняющихся программах. На уровне 2 находится механизм управления памятью, на 4 уровне - физическое управление в/в, на 5 уровне - файлами и логическими устройствами. Если процессу нужна память, то программа управления процессами обращается к другому элементу того же уровня - программе управления памятью.

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

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

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

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

Модель клиент-сервер и микроядра

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

Рисунок 4.3 - Структура ОС клиент-сервер

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

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

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

На одном краю этого спектра находится разрабатываемая фирмой IBM на основе микроядра Mach операционная система Workplace OS, придерживающаяся чистой микроядерной доктрины, состоящей в том, что все несущественные функции ОС должны выполняться не в режиме ядра, а в непривилегированном (пользовательском) режиме. На другом - Windows NT, в составе которой имеется исполняющая система (NT executive), работающая в режиме ядра и выполняющая функции обеспечения безопасности, ввода-вывода и другие.

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

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

Есть два пути решения этой проблемы. Один путь - разместить несколько таких, чувствительных к режиму работы процессора, серверов, в пространстве ядра, что обеспечит им полный доступ к аппаратуре и, в то же время, связь с другими процессами с помощью обычного механизма сообщений. Такой подход был использован, например, при разработке Windows NT: кроме микроядра, в привилегированном режиме работает часть Windows NT, называемая executive управляющей программой. Она включает ряд компонентов, которые управляют виртуальной памятью, объектами, вводом-выводом и файловой системой (включая сетевые драйверы), взаимодействием процессов, и частично системой безопасности.

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

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

Кроме уже представленных соображений, перемещение планировщика на пользовательский уровень может понадобиться для чисто коммерческих целей. Некоторые производители ОС (например, IBM и OSF со своими вариантами микроядра Mach) планируют лицензировать свое микроядро другим поставщикам, которым может потребоваться заменить исходный планировщик на другой, поддерживающий, например, планирование в задачах реального времени или реализующий какой-то специальный алгоритм планирования. А вот другая ОС - Windows NT, также использующая микроядерную концепцию - воплотила понятие приоритетов реального времени в своем планировщике, резидентно расположенном в ядре, и это не дает возможности заменить ее планировщик на другой.

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

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

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

Высокая степень переносимости обусловлена тем, что весь машинно-зависимый код изолирован в микроядре, поэтому для переноса системы на новый процессор требуется меньше изменений и все они логически сгруппированы вместе.

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

Расширяемость также является одним из важных требований к современным операционным системам. Является ли операционная система маленькой, как DOS, или большой, как UNIX, для нее неизбежно настанет необходимость приобрести свойства, не заложенные в ее конструкцию. Увеличивающаяся сложность монолитных операционных систем делала трудным, если вообще возможным, внесение изменений в ОС с гарантией надежности ее последующей работы. Ограниченный набор четко определенных интерфейсов микроядра открывает путь к упорядоченному росту и эволюции ОС.

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

Иногда имеется потребность и в сокращении возможностей ОС. На Windows NT или UNIX перешло бы большее число пользователей, если бы для этих операционных систем не требовалось 16 Мб оперативной памяти и 70 Мб и более пространства на жестком диске. Микроядро не обязательно подразумевает небольшую систему. Надстроенные службы, типа файловой системы и системы управления окнами, добавят к ней немало. Конечно же, не всем нужна безопасность класса C2 или распределенные вычисления. Если важные, но предназначенные для определенных потребителей свойства можно исключать из состава системы, то базовый продукт подойдет более широкому кругу пользователей.

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

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


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: