<< Пред. стр. 4 (из 8) След. >>
Принцип независимости программ от внешних устройств реализуется сейчас в подавляющем большинстве современных ОС. Этот принцип заключается в том, что связь программ с конкретными устройствами производится не на уровне трансляции программы, а в период планирования ее исполнения. В результате перекомпиляция при работе программы с новым устройством, на котором располагаются данные, не требуется. Указанный принцип позволяет осуществлять операции управления внешними устройствами одинаково и независимо от их конкретных физических характеристик. Например, программе, содержащей операции обработки последовательного набора данных, безразлично, на каком носителе эти данные будут располагаться. Смена носителя и данных, размещаемых на них (при неизменности структурных характеристик данных), не привнесет каких-либо изменений в программу, если в системе реализован принцип независимости.Одним из аспектов принципа совместимости является способность ОС выполнять программы, написанные для других ОС или для более ранних версий данной операционной системы, а также для другой аппаратной платформы. Необходимо разделять вопросы двоичной совместимости и совместимости на уровне исходных текстов приложений. Двоичная совместимость достигается в том случае, когда можно взять исполняемую программу и запустить ее на выполнение под другой ОС. Для этого необходимы: совместимость на уровне команд процессора, совместимость на уровне системных вызовов и даже на уровне библиотечных вызовов, если они являются динамически связываемыми. Совместимость на уровне исходных текстов требует наличия соответствующего транслятора в составе системного программного обеспечения, а также совместимости на уровне библиотек и системных вызовов. При этом необходима перекомпиляция имеющихся исходных текстов в новый выполняемый модуль. Гораздо сложнее достичь двоичной совместимости между процессорами, основанными на разных архитектурах. Для того, чтобы одна машина выполняла программы другой машины, она должна работать с машинными командами, которые ей изначально непонятны. Выходом в таких случаях является использование так называемых прикладных сред или эмуляторов. Учитывая, что основную часть программы, как правило, составляют вызовы библиотечных функций, прикладная среда имитирует библиотечные функции целиком, используя заранее написанную библиотеку функций аналогичного назначения, а остальные команды эмулирует каждую по отдельности. Одним из средств обеспечения совместимости программных и пользовательских интерфейсов является их соответствие стандартам POSIX. Использование стандартов POSIX позволяет создавать программы, которые впоследствии могут легко переноситься из одной системы в другую.
Принцип открытой и наращиваемой (модифицируемой, развиваемой) ОС позволяет не только использовать возможности генерации, но и вводить в ее состав новые модули, совершенствовать существующие и т. д. Другими словами, необходимо, чтобы можно было легко внести дополнения и изменения, если это потребуется, и не нарушить при этом целостность системы. Хорошие возможности для расширения предоставляет подход к структурированию ОС по типу клиент-сервер с использованием микроядерной технологии (см. подраздел 5.2). В соответствии с этим подходом ОС строится как совокупность привилегированной управляющей программы и набора непривилегированных услуг – «серверов». Основная часть ОС остается неизменной, но в то же время могут быть добавлены новые серверы или улучшены старые. Этот принцип иногда трактуют как принцип расширяемости системы.
Принцип мобильности (переносимости) заключается в том, что операционная система должна относительно легко переноситься с процессора одного типа на процессор другого типа и с аппаратной платформы одного типа (которая включает наряду с типом процессора также и способ организации всей аппаратуры машины, иначе говоря, архитектуру ВМ) на аппаратную платформу другого типа. Заметим, что принцип переносимости очень близок принципу совместимости, хотя это и не одно и то же. Написание переносимой ОС аналогично написанию любого переносимого кода. При этом нужно следовать некоторым правилам. Во-первых, большая часть ОС должна быть написана на языке, который имеется на всех машинах или системах, на которые планируется в дальнейшем ее переносить. Это, прежде всего, означает, что ОС должна быть написана на языке высокого уровня, предпочтительно стандартизованном, например на языке С. Программа, написанная на ассемблере, не является в общем случае переносимой. Во-вторых, важно минимизировать или, если возможно, исключить те части кода, которые непосредственно взаимодействуют с аппаратными средствами. Зависимость от аппаратуры может иметь много форм. Некоторые очевидные формы зависимости включают прямое манипулирование регистрами и другими аппаратными средствами. Наконец, если аппаратно-зависимый код не может быть полностью исключен, то он должен быть изолирован в нескольких хорошо локализуемых модулях. Аппаратно-зависимый код не должен быть распределен по всей системе. Например, можно спрятать аппаратно-зависимую структуру в программно задаваемые данные абстрактного типа. Другие модули системы будут работать с этими данными, а не с аппаратурой, используя набор некоторых функций. Когда ОС переносится, то изменяются только эти данные и функции, которые ими манипулируют. Именно введение стандартов POSIX преследовало цель обеспечить переносимость создаваемого программного обеспечения.
Принцип обеспечения безопасности при выполнении вычислений является желательным свойством для любой многопользовательской системы. Правила безопасности определяют такие свойства, как защита ресурсов одного пользователя от других и установление квот по ресурсам для предотвращения захвата одним пользователем всех системных ресурсов. Обеспечение защиты информации от несанкци-онированного доступа является обязательной функцией операционных систем. В соответствии со стандартами Национального центра компьютерной безопасности США (NCSC – National Computer Security Center) безопасной считается система, которая «посредством специальных механизмов защиты контролирует доступ к информации таким образом, что только имеющие соответствующие полномочия лица или процессы, выполняющиеся от их имени, могут получить доступ на чтение, запись, создание или удаление информации». Иерархия уровней безопасности отмечает низший уровень безопасности как D, а высший – как А. В класс D попадают системы, оценка которых выявила их несоответствие требованиям всех других классов. Основными свойствами, характерными для систем класса (уровня) С, являются наличие подсистемы учета событий, связанных с безопасностью, и избирательный контроль доступа. На уровне С должны присутствовать:
а) средства секретного входа, обеспечивающие идентификацию пользователей путем ввода уникального имени и пароля перед тем, как им будет разрешен доступ к системе;
б) избирательный контроль доступа, позволяющий владельцу ресурса определить, кто имеет доступ к ресурсу и что он может с ним делать (владелец осуществляет это путем предоставляемых прав доступа пользователю или группе пользователей);
в) средства учета и наблюдения, обеспечивающие возможность обнаружить и зафиксировать важные события, связанные с безопас-ностью, или любые попытки получить доступ или удалить системные ресурсы;
г) защита памяти, заключающаяся в том, что память инициализи-руется перед тем, как повторно используется.
На этом уровне система не защищена от ошибок пользователя, но поведение его может быть проконтролировано по записям в журнале, составленным средствами наблюдения и аудита. Системы уровня В основаны на помеченных данных и распределении пользователей по категориям, то есть реализуют мандатный контроль доступа. Каждому пользователю присваивается рейтинг защиты, и он может получать доступ к данным только в соответствии с этим рейтингом. Этот уровень в отличие от уровня С защищает систему от ошибочного поведения пользователя. Уровень А является самым высоким уровнем безопасности и в дополнение ко всем требованиям уровня В требует выполнения формального, математически обоснованного доказательства соответствия системы требованиям безопасности.
5.2. Архитектурные особенности проектирования
операционных систем
Для удовлетворения жестких требований, предъявляемых к современной ОС, большое значение имеет ее структурное построение. Операционные системы прошли длительный путь развития от монолитных систем до хорошо структурированных модульных систем, способных к развитию, расширению и легкому переносу на новые платформы.
В общем случае «структура» монолитной ОС представляет собой как раз отсутствие структуры. Такая ОС написана как набор процедур, каждая из которых может вызывать другие, когда ей это нужно. При использовании этой техники каждая процедура системы имеет хорошо определенный интерфейс в терминах параметров и результатов, и каждая может вызвать любую другую для выполнения некоторой нужной для нее полезной работы. Для построения монолитной системы необходимо скомпилировать все отдельные процедуры, а затем связать их вместе в единый объектный файл с помощью компоновщика. Каждая процедура видит любую другую процедуру (в отличие от структуры, содержащей модули, в которой большая часть информации является локальной для модуля, и процедуры модуля можно вызвать только через специально определенные точки входа). Однако даже такие монолитные системы могут быть «немного» структурированными. При обращении к системным вызовам, поддерживаемым ОС, параметры помещаются в строго определенные места, такие, как регистры или стек, а затем выполняется специальная команда прерывания, известная как вызов ядра или вызов супервизора. Эта команда переключает машину из режима пользователя в режим ядра, называемый также режимом супервизора, и передает управление ОС. Затем ОС проверяет параметры вызова для того, чтобы определить, какой системный вызов должен быть выполнен. После этого ОС индексирует таблицу, содержащую ссылки на процедуры, и вызывает соответствующую процедуру. Такая организация ОС предполагает следующую структуру:
1. Главная программа, которая вызывает требуемые сервисные процедуры;
2. Набор сервисных процедур, реализующих системные вызовы;
3. Набор утилит, обслуживающих сервисные процедуры.
В этой модели для каждого системного вызова имеется одна сервисная процедура. Утилиты выполняют функции, которые нужны нескольким сервисным процедурам.
Обобщением предыдущего подхода является организация ОС как иерархии уровней. Уровни образуются группами функций операционной системы, таких как файловая система, управление процессами и устройствами и т.п. Каждый уровень может взаимодействовать только со своим непосредственным соседом – выше- или нижележащим уровнем. Прикладные программы или модули самой операционной системы передают запросы вверх и вниз по этим уровням. Такой структурный подход с современной точки зрения воспринимается как монолитный. В системах, имеющих многоуровневую структуру, нелегко удалить один слой и заменить его другим в силу множественности и размытости интерфейсов между слоями. Добавление новых функций и изменение существующих требует значительного объема работ. Поэтому на смену монолитному подходу была предложена модель клиент-сервер и тесно связанная с ней концепция микроядра.
Модель клиент-сервер – это один из возможных подходов к структурированию ОС. В широком смысле модель клиент-сервер предполагает наличие, во-первых, программного компонента – потребителя какого-либо сервиса, то есть клиента, и во-вторых, программного компонента – поставщика этого сервиса, то есть сервера. Взаимодействие между клиентом и сервером стандартизуется, так что сервер способен обслуживать клиентов, реализованных различными способами и, может быть, разными производителями. При этом главным требованием является то, чтобы они запрашивали услуги сервера понятным ему способом. Инициатором обмена обычно является клиент, который посылает запрос на обслуживание серверу, находящемуся в состоянии ожидания запроса. Один и тот же программный компонент может быть клиентом по отношению к одному виду услуг, и сервером для другого вида услуг. Модель клиент-сервер является скорее удобным концептуальным средством ясного представления функций того или иного программного элемента в той или иной ситуации, нежели технологией. Эта модель успешно применяется не только при построении ОС, но и на всех уровнях программного обеспечения, и имеет в некоторых случаях более узкий, специфический смысл, сохраняя, естественно, при этом все свои общие черты. Применительно к структурированию операционной системы идея состоит в разбиении ОС на несколько процессов – серверов, каждый из которых выполняет отдельный набор сервисных функций, например, управление памятью, создание или планирование процессов. Каждый сервер выполняется в пользовательском режиме. Клиент, которым может быть либо другой компонент ОС, либо прикладная программа, запрашивает сервис, посылая сообщение на сервер. Ядро ОС (называемое здесь микроядром), работая в привилегированном режиме, доставляет сообщение нужному серверу, сервер выполняет операцию, после чего ядро возвращает результаты клиенту с помощью другого сообщения. Подход с использованием микроядра заменил вертикальное распределение функций операционной системы на горизонтальное. Компоненты, лежащие выше микроядра, хотя и используют сообщения, пере-сылаемые через микроядро, взаимодействуют друг с другом непосредственно. Микроядро играет роль регулировщика. Оно проверяет сообщения, пересылает их между серверами и клиентами, предоставляет доступ к аппаратуре.
Рассмотренная теоретическая модель является идеализированным описанием системы клиент-сервер, в которой ядро состоит только из средств передачи сообщений. В действительности разные варианты реализации модели клиент-сервер в структуре ОС могут существенно различаться по объему работ, выполняемых в режиме ядра. На одном краю этого спектра находится чисто микроядерная доктрина, состоящая в том, что все несущественные функции ОС должны выполняться не в режиме ядра, а в непривилегированном (пользовательском) режиме. На другом краю спектра – операционные системы, в составе которых имеется исполняющая система, работающая в режиме ядра и выполняющая функции обеспечения безопасности, ввода-вывода и другие.
Микроядро реализует жизненно важные функции, лежащие в основе ОС. Это базис для менее существенных системных служб и приложений. Именно вопрос о том, какие из системных функций считать несущественными, и, соответственно, не включать их в состав ядра, является предметом спора среди соперничающих сторонников идеи микроядра. В общем случае, подсистемы, бывшие традиционно неотъемлемыми частями операционной системы – файловые системы, системы управление окнами и системы обеспечения безопасности – становятся периферийными модулями, взаимодействующими с ядром и друг с другом. Главный принцип разделения работы между микроядром и окружающими его модулями – включать в микроядро только те функции, которым абсолютно необходимо исполняться в режиме супервизора и в привилегированном пространстве. Под этим обычно подразумеваются машиннозависимые программы (включая поддержку нескольких процессоров), некоторые функции управления процессами, обработка прерываний, поддержка пересылки сообщений, некоторые функции управления устройствами ввода-вывода, связанные с загрузкой команд в регистры устройств. Эти функции операционной системы трудно, если не невозможно, выполнить программам, работающим в пространстве пользователя.
Известны два пути решения этой проблемы. Один из этих путей – размещение нескольких серверов, чувствительных к режиму работы процессора, в пространстве ядра, что обеспечивает им полный доступ к аппаратуре и, в то же время, связь с другими процессами посредством обычного механизма сообщений. Другой путь заключается в том, чтобы оставить в ядре только небольшую часть сервера, представляющую собой механизм реализации решения, а часть, отвечающую за принятие решения, переместить в пользовательскую область. Этот подход требует тесного взаимодействия между внешним планировщиком и резидентным диспетчером. Важно подчеркнуть логику последнего подхода. Несмотря на то, что, вообще говоря, запуск процесса или потока требует доступа к аппаратуре и обычно является функцией ядра, но при этом ядру все равно, какой из процессов запускать, поэтому решения о приоритетах процессов и дисциплине постановки в очередь может принимать работающий вне ядра планировщик.
Как и управление процессами, управление памятью может распределяться между микроядром и сервером, работающим в пользовательском режиме. Система управления страничной памятью (пейджер), работающая вне ядра, определяет стратегию замещения страниц (т.е. решает, какие страницы следует удалить из памяти для размещения страниц, выбранных с диска в ответ на прерывание по отсутствию необходимой страницы), а микроядро выполняет перемещение выбранных пейджером страниц. Как и планировщик процессов, пейджер является заменяемой составной частью.
Драйверы устройств также могут располагаться как внутри ядра, так и вне его. При размещении драйверов устройств вне микроядра для обеспечения возможности разрешения и запрещения прерываний часть программы драйвера должна исполняться в пространстве ядра. Отделение драйверов устройств от ядра делает возможной динамическую конфигурацию ОС. Кроме динамической конфигурации, есть и другие причины рассматривать драйверы устройств в качестве процессов пользовательского режима. Например, какая-либо система управления базами данных может иметь свой драйвер, оптимизированный под конкретный вид доступа к диску, но его нельзя будет подключить, если драйверы будут расположены в ядре. Этот подход также способствует переносимости системы, так как функции драйверов устройств могут быть во многих случаях абстрагированы от аппаратной части.
Технология микроядер обеспечивает совместимость программ, написанных для разных ОС, за счет абстрагирования интерфейсов прикладных программ от расположенных ниже операционных систем. Высокая степень переносимости обусловлена тем, что весь машиннозависимый код изолирован в микроядре, поэтому для переноса системы на новый процессор требуется меньше изменений и все они логически сгруппированы вместе.
Одним из важнейших требований, предъявляемых к ОС, является возможность расширяемости операционной системы. Практически для любой ОС неизбежно наступает время, когда возникает острая необходимость привнесения в систему новых функций и свойств, которые не были заложены в нее первоначально. Для монолитных операционных систем внесение изменений затруднительно и чаще всего вообще невозможно. В микроядерных структурах благодаря наличию ограниченного набора четко определенных интерфейсов возможна постепенная эволюция и расширение ОС.
Обычно операционная система выполняется только в режиме ядра, а прикладные программы – только в режиме пользователя (за исключением тех случаев, когда они обращаются к ядру за выполнением системных функций). В отличие от обычных систем, операционная система, построенная на микроядре, выполняет свои серверные подсистемы в режиме пользователя как обычные прикладные программы. Такая структура позволяет изменять и добавлять серверы, не влияя на целостность микроядра.
Иногда имеется потребность и в сокращении возможностей ОС. Микроядро не обязательно подразумевает небольшую систему. Надстроенные службы, типа файловой системы и системы управления окнами, добавляют к ней немало. Если некоторые свойства являются важными, но предназначены лишь для определенных потребителей, можно исключать их из состава системы. Тогда базовый продукт подойдет более широкому кругу пользователей.
Использование модели клиент-сервер повышает надежность системы. Каждый сервер выполняется в виде отдельного процесса в своей собственной области памяти и таким образом защищен от других процессов. Более того, поскольку серверы выполняются в пространстве пользователя, они не имеют непосредственного доступа к аппаратуре и не могут модифицировать память, в которой хранится управляющая программа. И если отдельный сервер может потерпеть «крах», то он может быть перезапущен без останова или повреждения остальной части ОС. Эта модель хорошо подходит для распределенных вычислений, так как отдельные серверы могут работать на разных процессорах многопроцессорной ВМ или даже на разных ВМ. При получении от процесса сообщения микроядро может обработать его самостоятельно или переслать другому процессу. Так как микроядру безразлично, пришло ли сообщение от локального или удаленного процесса, подобная схема передачи сообщений является эффективным базисом для механизма RPC. Однако такая гибкость имеет свои недостатки: пересылка сообщений не так быстра, как обычные вызовы функций, и ее оптимизация является критическим фактором успеха ОС на основе микроядра.
Хотя технология микроядер и заложила основы модульных систем, способных развиваться регулярным образом, она не смогла в полной мере обеспечить возможности расширения систем. В настоящее время этой цели в наибольшей степени соответствует объектно-ориентированный подход, при котором каждый программный компонент является функционально изолированным от других. Основным понятием этого подхода является «объект». Объект – это единица программ и данных, взаимодействующая с другими объектам посредством приема и передачи сообщений. Объект может быть представлением как некоторых конкретных вещей – прикладной программы или документа, так и некоторых абстракций – процесса, события. Функции объекта определяют перечень действий, которые могут быть выполнены над данными этого объекта. Объект-клиент может обратиться к другому объекту, послав сообщение с запросом на выполнение какой-либо функции объекта-сервера. Объекты могут описывать сущности, которые они представляют, с разной степенью детализации. Для обеспечения преемственности при переходе к более детальному описанию предлагается механизм наследования свойств уже существующих объектов, то есть механизм, позволяющий порождать конкретные объекты из более общих. Например, при наличии объекта «текстовый документ» разработчик может легко создать объект «текстовый документ в формате Word», добавив соответствующее свойство к базовому объекту. Механизм наследования позволяет создать иерархию объектов, в которой каждый объект более низкого уровня приобретает все свойства своего предка.
Внутренняя структура данных объекта скрыта от наблюдения. Нельзя произвольно изменять данные объекта. Для того, чтобы получить данные из объекта или поместить данные в объект, необходимо вызывать соответствующие объектные функции. Это изолирует объект от того кода, который использует его. Разработчик может обращаться к функциям других объектов, или строить новые объекты путем наследования свойств других объектов, ничего не зная о том, как они сконструированы. Это свойство называется инкапсуляцией.
Таким образом, объект предстает для внешнего мира в виде «черного ящика» с хорошо определенным интерфейсом. С точки зрения разработчика, использующего объект, пока внешняя реакция объекта остается без изменений, не имеют значения никакие изменения во внутренней реализации. Это дает возможность легко заменять одну реализацию объекта на другую, например, в случае смены аппаратных средств. При этом сложное программное окружение, в котором находятся заменяемые объекты, не потребует никаких изменений. С другой стороны, способность объектов представать в виде «черного ящика» позволяет упаковывать в них и представлять в виде объектов уже существующие приложения, ничего в них не изменяя.
Использование объектно-ориентированного подхода особенно эффективно при создании активно развивающегося программного обеспечения, например, при разработке приложений, предназначенных для выполнения на разных аппаратных платформах.
Полностью объектно-ориентированные операционные системы очень привлекательны для программистов, так как позволяют им работать в глубине ОС, приспосабливая их к своим нуждам, но при этом не нарушая целостность системы.
Концепция объектно-ориентированного подхода непосредственно касается только разработчиков и лишь косвенно влияет на конечного пользователя. Другая концепция – концепция множественных прикладных сред – приносит пользователю возможность выполнять при помощи своей ОС программы, написанные для других операционных систем и других процессоров. Хотя в некоторых ОС дополнительное программное обеспечение позволяет пользователям запускать «чужие» программы, но в новом поколении операционных систем средства для выполнения «чужих» программ становятся стандартной частью системы. Благодаря этому операционная система практически не ограничивает выбор прикладных программ. Множественные прикладные среды обеспечивают совместимость конкретной ОС с приложениями, написанными для других ОС и процессоров, на двоичном уровне, а не на уровне исходных текстов.
При реализации множественных прикладных сред разработчики сталкиваются с противоречивыми требованиями. С одной стороны, задачей каждой прикладной среды является выполнение программы по возможности так, как если бы она выполнялась на «родной» ОС. Но потребности этих программ могут входить в конфликт с конструкцией операционной системы. Специализированные драйверы устройств могут противоречить требованиям безопасности. Могут конфликтовать схемы управления памятью и оконные системы. Но самой большой потенциальной проблемой является производительность – прикладная среда должна выполнять программы с приемлемой скоростью. Этому требованию не могут удовлетворить широко используемые ранее эмулирующие системы. Для сокращения времени на выполнение «чужих» программ прикладные среды используют имитацию программ на уровне библиотек. Эффективность этого подхода связана с тем, что большинство сегодняшних программ работают под управлением графических интерфейсов пользователя (Graphic User Interface – GUI), при этом приложения тратят большую часть времени, производя некоторые хорошо предсказуемые вещи. Они непрерывно выполняют вызовы библиотек GUI для манипулирования окнами и для других связанных с GUI действий. Тщательно продуманная прикладная среда имеет в своем составе библиотеки, имитирующие внутренние библиотеки GUI, но написанные на «родном» коде, то есть она совместима с программным интерфейсом другой ОС. Иногда такой подход называют трансляцией для того, чтобы отличать его от более медленного процесса эмулирования кода по одной команде за один раз.
С позиции использования прикладных сред более предпочтительным является способ написания программ, при котором программист для выполнения некоторой функции обращается с вызовом к ОС, а не пытается более эффективно реализовать эквивалентную функцию самостоятельно, работая напрямую с аппаратурой.
Модульность операционных систем нового поколения позволяет намного легче реализовать поддержку множественных прикладных сред. В отличие от старых операционных систем, состоящих из одного большого блока, предназначенного для всех практических применений и разбитого произвольным образом на части, новые системы являются модульными, с четко определенными интерфейсами между составляющими. Это делает создание дополнительных модулей, объединяющих эмуляцию процессора и трансляцию библиотек, значительно более простым действием.
5.3. Принципы построения системных и прикладных программных интерфейсов
Операционная система всегда выступает как интерфейс между аппаратурой машины и пользователем с его задачами. Под интерфейсами операционных систем понимают специальные системные и прикладные программные интерфейсы, предназначенные для выполнения ниже перечисленных задач.
1. Управление процессами, которое включает в себя следующий набор основных функций:
– запуск, приостановка и снятие процесса с выполнения;
– задание или изменение приоритета процесса;
– взаимодействие процессов между собой (механизмы семафоров, мьютексов и т.п.);
– удаленный вызов процедур (подпрограмм).
2. Управление памятью, которое включает в себя следующий набор основных функций:
– запрос на выделение блока памяти;
– освобождение блока памяти;
– изменение параметров блока памяти (например, память может быть заблокирована процессом либо предоставлена в общий доступ);
– отображение файлов на память (имеется не во всех системах).
3. Управление вводом-выводом, которое включает в себя запросы на управление виртуальными устройствами ввода-вывода, файловые операции (запросы к системе управления файлами на создание, изменение и удаление данных, организованных в файлы).
Выше отмечены основные наборы функций, которые выполняются ОС по соответствующим запросам от процессов. Что касается пользовательского интерфейса операционной системы, то он реализуется с помощью специальных программных модулей, которые принимают его команды на соответствующем языке (возможно, с использованием графического интерфейса) и транслируют их в обычные вызовы в соответствии с основным интерфейсом системы. Обычно эти модули называют интерпретатором команд. Получив от пользователя команду, такой модуль после лексического и синтаксического анализа либо сам выполняет действие, либо (что случается чаще) обращается к другим модулям ОС, используя механизм прикладного программного интерфейса API.
Обращения к операционной системе в соответствии с имеющимся API может осуществляться как посредством вызова подпрограммы с передачей ей необходимых параметров, так и через механизм программных прерываний. Выбор метода реализации вызовов функций API должен определяться архитектурой платформы.
В большинстве ОС используется метод вызова подпрограмм. В этом случае вызов сначала передается в модуль API (например, это может быть библиотека времени выполнения – RTL, Run Time Library), который и перенаправляет вызов соответствующим обработчикам программных прерываний, входящим в состав ОС. Использование механизма прерываний вызвано, главным образом, тем, что при этом процессор переводится в режим супервизора.
Прикладной программный интерфейс API, как это и следует из его названия, предназначен для использования прикладными программами системных ресурсов ОС и реализуемых ею функций. API описывает совокупность функций и процедур, принадлежащих ядру или надстройкам ОС, и предоставляет разработчику прикладной программы набор функций, ориентированных на организацию взаимодействия результирующей прикладной программы с так называемой «целевой вычислительной системой», которая представляет собой совокупность программных и аппаратных средств, в окружении которых выполняется результирующая программа. Сама результирующая программа порождается системой программирования на основании кода исходной программы, созданного разработчиком, а также объектных модулей и библиотек, входящих в состав системы программирования. Функции API позволяют разработчику строить результирующую прикладную программу так, чтобы использовать средства целевой вычислительной системы для выполнения типовых операций. При этом разработчик программы избавлен от необходимости создания исходного кода для выполнения этих операций.
Программный интерфейс API включает в себя не только сами функции, но и соглашения об их использовании, которые регламентируются операционной системой, архитектурой целевой вычислительной системы и системой программирования.
Существует несколько вариантов реализации API:
- реализация на уровне ОС;
- реализация на уровне системы программирования;
- реализация на уровне внешней библиотеки процедур и функций.
Система программирования в каждом из этих вариантов предоставляет разработчику средства для подключения функций API к исходному коду программы и организации их вызовов. Объектный код функций API подключается к результирующей программе компоновщиком при необходимости.
При реализации функций API на уровне ОС за их выполнение ответственность несет ОС. Объектный код, выполняющий функции, либо непосредственно входит в состав ОС (или даже ядра ОС), либо поставляется в составе динамически загружаемых библиотек, разработанных для данной ОС. Система программирования ответственна только за то, чтобы организовать интерфейс для вызова этого кода. В таком варианте результирующая программа обращается непосредственно к ОС. Поэтому достигается наибольшая эффективность выполнения функций API по сравнению со всеми другими вариантами реализации API. Недостатком организации API по такой схеме является практически полное отсутствие переносимости не только кода результирующей программы, но и кода исходной программы. Программа, созданная для одной архитектуры ВМ, не сможет исполняться на ВМ другой архитектуры даже после того, как ее объектный код будет полностью перестроен. Чаще всего система программирования не сможет выполнить перестроение исходного кода для новой архитектуры ВМ, поскольку многие функции API, ориентированные на определенную ОС, будут в новой архитектуре просто отсутствовать. Таким образом, в данной схеме для переноса прикладной программы с одной целевой вычислительной системы на другую будет требоваться изменение исходного кода программы.
Если функции API реализуются на уровне системы программирования, они предоставляются пользователю в виде библиотеки функций соответствующего языка программирования (обычно речь идет о библиотеке RTL, которая включает в себя стандартные программы, поставляемые системой программирования на этапе компиляции). Эффективность функций API в таком варианте будет несколько ниже, чем при непосредственном обращении к функциям ОС, так как для выполнения многих функций API библиотека RTL языка программирования должна все равно выполнять обращения к функциям ОС. Однако переносимость исходного кода программы в таком варианте будет самой высокой, поскольку синтаксис и семантика всех функций будут строго регламентированы в стандарте соответствующего языка программирования. Они зависят от языка и не зависят от архитектуры целевой вычислительной системы. Поэтому для выполнения прикладной программы на новой архитектуре достаточно заново построить код результирующей программы с помощью соответствующей системы программирования.
При реализации функций API с помощью внешних библиотек они предоставляются пользователю в виде библиотеки процедур и функций, созданной сторонним разработчиком. Причем разработчиком такой библиотеки может выступать тот же самый производитель. Система программирования ответственна только за то, чтобы подключить объектный код библиотеки к результирующей программе. Причем внешняя библиотека может быть и динамически загружаемой (то есть загружаемой во время выполнения программы). С точки зрения эффективности выполнения этот метод реализации API имеет самые низкие результаты, поскольку внешняя библиотека обращается как к функциям ОС, так и к функциям RTL языка программирования. Только при очень высоком качестве внешней библиотеки ее эффективность становится сравнимой с библиотекой RTL. Если говорить о переносимости исходного кода, то здесь существует только одно требование – используемая внешняя библиотека должна быть доступна в любой из архитектур, на которые ориентирована прикладная программа. Тогда удается достигнуть переносимости. Это возможно, если используемая библиотека удовлетворяет какому-то принятому стандарту, а система программирования поддерживает этот стандарт.
Резюме
Основными принципами построения современных эффективных операционных систем являются принципы модульности, генерируемости, функциональной избыточности, виртуализации, независимости выполняемых программ от внешних устройств, совместимости с другими ОС, открытости, легкой наращиваемости, мобильности (переносимости на другие аппаратные платформы), обеспечения надежной безопасности.
При модульном построении в ОС выделяется некоторая часть важных программных модулей, которые для более эффективной организации вычислительного процесса должны постоянно находиться в оперативной памяти. Эту часть ОС называют ядром операционной системы. Помимо программных модулей, входящих в состав ядра и постоянно располагающихся в оперативной памяти, может быть множество других системных программных модулей, которые загружаются в оперативную память только при необходимости, а в случае отсутствия свободного пространства могут быть замещены другими подобными модулями. Такие модули получили название транзитных или диск-резидентных.
Операционные системы прошли длительный путь развития и совершенствования своей архитектуры от монолитных систем до хорошо структурированных модульных систем, способных к развитию, расширению и легкому переносу на новые платформы. Монолитная ОС представляет собой набор процедур, каждая из которых имеет определенный интерфейс и может вызывать любую другую процедуру для выполнения некоторой нужной для нее полезной работы. При построении монолитной системы все отдельные процедуры связываются вместе в единый объектный файл.
Обобщением предыдущего подхода является организация ОС как иерархии уровней. Уровни образуются группами функций операционной системы, таких как файловая система, управление процессами и устройствами и т.п. Каждый уровень может взаимодействовать только со своим непосредственным соседом – выше- или нижележащим уровнем. Процессы передают запросы вверх и вниз по этим уровням. Такой структурный подход также воспринимается как монолитный. На смену монолитному подходу пришла модель клиент-сервер и тесно связанная с ней концепция микроядра.
Модель клиент-сервер предполагает наличие, во-первых, программного компонента – потребителя какого-либо сервиса, то есть клиента, а во-вторых, программного компонента – поставщика этого сервиса, то есть сервера. Взаимодействие между клиентом и сервером стандартизуется, так что сервер способен обслуживать клиентов, реализованных различными способами и, может быть, разными производителями. Ядро ОС (называемое здесь микроядром), работая в привилегированном режиме, доставляет сообщение нужному серверу, сервер выполняет операцию, после чего ядро возвращает результаты клиенту с помощью другого сообщения. Подход с использованием микроядра заменил вертикальное распределение функций (в монолитных ОС) на горизонтальное.
Технология микроядер заложила основы модульных систем, способных развиваться регулярным образом. Благодаря наличию четко определенных интерфейсов возможна постепенная эволюция и расширение ОС.
Достижению целей легкой расширяемости ОС в наибольшей степени соответствует объектно-ориентированный подход, при котором каждый программный компонент является функционально изолированным от других.
Модульность операционных систем нового поколения позволяет намного легче реализовать поддержку множественных прикладных сред, которые обеспечивают совместимость (на двоичном уровне) конкретной ОС с приложениями, написанными для других ОС и процессоров.
Под интерфейсами операционных систем понимают специальные системные и прикладные программные интерфейсы, предназначенные для управления процессами, памятью и вводом-выводом. Для использования прикладными программами системных ресурсов ОС и реализуемых ею функций предназначен прикладной программный интерфейс API, который может быть реализован на уровне ОС, на уровне системы программирования или на уровне внешней библиотеки процедур и функций.
Контрольные вопросы и задания
1. Перечислите основные принципы построения операционных систем.
2. Опишите принцип модульности построения ОС.
3. Охарактеризуйте принцип генерируемости ОС.
4. Какие преимущества дает реализация принципа функциональной избыточности?
5. Изложите основные положения принципа виртуализации.
6. В чем заключается принцип независимости программ от внешних устройств?
7. Что дает на практике построение ОС с учетом принципа совместимости?
8. Покажите практическое значение принципа переносимости ОС.
9. Опишите принципы обеспечения безопасности.
10. Перечислите и охарактеризуйте основные структурные модели, применяемые при проектировании ОС.
11. Для выполнения каких задач предназначены системные и прикладные программные интерфейсы?
12. Какие возможности предоставляют разработчику программного обеспечения функции прикладного программного интерфейса?
13. Опишите основные варианты реализации функций прикладного программного интерфейса, укажите их достоинства и недостатки.6. История развития операционных систем
и эволюция их функциональных характеристик
6.1. Операционные системы разных этапов разработки вычислительных машин
Зарождение прообразов операционных систем в современном их толковании относят к периоду разработки в середине 1950-х годов вычислительных машин на полупроводниковой элементной базе (так называемого второго поколения ВМ) и появления первых систем пакетной обработки информации. Системы пакетной обработки (которые просто автоматизировали запуск одной программ за другой и тем самым увеличивали коэффициент загрузки процессора) явились прообразом современных операционных систем, они стали первыми системными программами, предназначенными для управления вычислительным процессом. В ходе реализации систем пакетной обработки был разработан формализованный язык управления заданиями, с помощью которого программист сообщал системе и оператору, какую работу он хочет выполнить на вычислительной машине. Совокупность нескольких заданий, как правило, в виде набора перфокарт, получила название пакета заданий.
Следующим важным этапом развития ВМ стал переход в 1960-х годах от отдельных полупроводниковых элементов типа транзисторов к интегральным микросхемам, что привело к разработке более мощных вычислительных машин третьего поколения. Этот этап характеризуется созданием семейств программно-совместимых машин. Первым таким семейством была серия машин IBM/360 корпорации IBM (International Business Machines), построенных на интегральных микросхемах. Это семейство значительно превосходило ВМ второго поколения по удельному критерию производительность/стоимость. Вскоре идея программно-совместимых машин стала общепризнанной. Программная совместимость требовала и совместимости операционных систем. Такие ОС системы должны были работать как на больших, так и на малых ВМ, с различным количеством разнообразной периферии, в коммерческой области и в области научных исследований. Разработанные в то время операционные системы, в которых делалась попытка удовлетворения указанных противоречивых требований, оказывались чрезвычайно сложными. Они состояли из многих миллионов ассемблерных строк, написанных тысячами программистов, и, как правило, содержали множество ошибок. Однако, несмотря на огромные размеры и множество проблем, операционная система OS/360 и другие ей подобные ОС машин третьего поколения действительно удовлетворяли большинству требований потребителей. Важнейшим достижением ОС этого поколения явилась реализация мультипрограммного режима, когда на одном процессоре попеременно выполняется несколько программ. Мультипрограммный режим работы процессора значительно сократил время его простоев, которые были присущи однопрограммному режиму (при котором, например, процессор мог быть не загружен работой в ряде операций одной выполняемой программы). При мультипрограммном режиме каждая из выполняемых программ загружалась в свой участок (раздел) оперативной памяти. Другим нововведением стал спулинг (описанный выше в разделе 2), определявшийся в то время как способ организации вычислительного процесса, в соответствии с которым задания считывались с перфокарт на диск в том темпе, в котором они появлялись в очереди к устройству ввода, а затем, когда очередное задание завершалось, новое задание с диска загружалось в освободившийся раздел.
Наряду с организацией мультипрограммного режима для систем пакетной обработки появился новый тип ОС – системы разделения времени. Вариант мультипрограммного режима, применяемый в системах разделения времени, был нацелен на создание для каждого отдельного пользователя иллюзии единоличного использования вычислительной машины.
Следующий период в эволюции операционных систем связан с появлением больших интегральных схем (БИС). В 1980-х годах произошло резкое возрастание степени интеграции и удешевление микросхем. ВМ стала доступна отдельному человеку, и наступила эра персональных ВМ (чаще называемых более устоявшимся термином –«персональные компьютеры»). С точки зрения архитектуры персональные ВМ практически ничем не отличались от класса миниВМ, например, самых распространенных в мире на тот период времени миниВМ типа PDP-11, но их цены были существенно ниже. Если миниВМ давали возможность иметь собственную ВМ отдельному подразделению предприятия или образовательному учреждению, то персональный компьютер сделал это возможным для отдельного человека. ВМ стали широко использоваться неспециалистами, что потребовало разработки так называемого «дружественного» программного обеспечения.
На рынке операционных систем стали доминировать системы двух классов: многопользовательские многозадачные (мультипрограммные) ОС клона UNIX и однопользовательские однозадачные (однопрограммные) ОС клона MS-DOS.
История развития операционных систем клона UNIX, эволюция их функциональных характеристик, а также описание современных версий UNIX представлены далее в подразделе 6.2.
Операционные системы корпорации Microsoft под названием MS-DOS (MicroSoft Disk Operating System – «дисковая операционная система от Microsoft») были разработана для персональных компьютеров, построенных на базе микропроцессоров Intel 8088, а затем 80286, 80386 и 80486. История операционной системы MS-DOS, получившей широчайшее распространение во всем мире, начинается со скромной системы 86-DOS, написанной в 1980 г. При разработке 86-DOS были учтены требования совместимости с весьма популярной в то время системой СР/М-80 (Control Program for Microcomputers – программа управления для микрокомпьютеров), предназначенной для восьмиразрядных микрокомпьютеров на базе процессоров Intel 8080 и Zylog Z-80. В июле 1981 г. корпорация Microsoft приобрела права на систему 86-DOS, существенно переработала ее и выпустила на рынок под торговой маркой MS-DOS. Когда в 1981 г., когда появились первые персональные компьютеры корпорации IBM, система MS-DOS 1.0 и ее аналог PC-DOS 1.0 (разработка IBM для персональных компьютеров – Personal Computer, PC) быстро стали основными системами для этих машин. В то же время непрерывное развитие аппаратных средств компьютеров и накопление опыта работы с ними привели к необходимости столь же непрерывного совершенствования исходных систем MS-DOS и PC-DOS. В дальнейшем они развивались параллельно и их новые версии практически во всем соответствовали друг другу. Первое серьезное усовершенствование MS-DOS (версия 2.0) было выполнено в 1983 г. Фактически была выпущена новая операционная система, хотя разработчикам удалось обеспечить полную совместимость с MS-DOS 1.0. В систему MS-DOS 2.0 были включены следующие новшества:
– поддержка дискет с повышенной плотностью записи и, главное, появившихся к этому времени жестких дисков;
– иерархическая структура каталогов (пришедшая из системы UNIX) вместе с группой команд ее поддержки;
– утилита PRINT, обеспечивающая вывод на печать в фоновом режиме с возможностью одновременного выполнения любой программы;
– атрибуты файлов и их системная поддержка;
– устанавливаемые драйверы внешних устройств;
– динамическое выделение и освобождение памяти;
– расширение возможностей командных файлов;
– большая группа новых команд, утилит и драйверов устройств, а также ряди других новшеств.
Система MS-DOS 3.0 появилась в 1984 г., одновременно с выпуском компьютеров IBM PC/AT на базе процессоров 80286. Начиная с этой версии в MS-DOS входит поддержка расширенной памяти, жестких дисков увеличенного объема, разделяемых файлов. Начиная с версии 3.1 в MS-DOS включается поддержка сетевых структур. В 1988 г. разработана версия MS-DOS 4.0, в которую была включена поддержка разделов на жестких дисках, превышающих 32 Мбайт, средства эмуляции дополнительной памяти, а также ряд новых команд. Наиболее привлекательной чертой MS-DOS 5.0 явилась возможность организации на компьютерах с расширенной памятью специальных областей, куда можно загружать устанавливаемые драйверы, резидентные программы и большую часть самой DOS. Это позволило существенно увеличить объем памяти, отводимой прикладным программам (до 600 – 610 Кбайт). Операционная система MS-DOS 6.0, выпущенная в 1993 г., вобрала в себя все лучшие качества предыдущих версий. В систему был включен целый ряд полноэкранных инструментальных утилит, охватывающих широкий диапазон потребностей пользователей персональных компьютеров. Утилиты имели развитый интерфейс пользователя, могли управляться как от клавиатуры, так и мышью, включали контекстные справочники и элементы обучающих систем. Важнейшим усовершенствованием, введенным в версию MS-DOS 6.0, явилась возможность задания в процессе начальной загрузки альтернативных конфигураций системы (методика использования расширенной и дополнительной памяти, состав загружаемых драйверов устройств, наличие и характеристики электронных дисков и пр.).
Управление компьютером при помощи команд DOS требует определенных знаний, большой аккуратности и внимания. Для того, чтобы сделать общение с компьютером более простым, были разработаны специальные программы-оболочки. Операционная оболочка – это такая программа, которая позволяет пользователю осуществлять действия по управлению ресурсами компьютера в рамках более развитого (более удобного и интуитивно понятного) интерфейса, чем командная строка. Начиная с версии 4.0 в MS-DOS входила собственная псевдографическая оболочка SHELL, однако наибольшую популярность среди оболочек DOS завоевал пакет программ Norton Commander фирмы Symantec. Использование операционной оболочки Norton Commander значительно yпростило управление компьютером, позволило в наглядном виде получать информацию о его основных ресурсах (и их загруженности), осуществлять все основные процедуры управления компьютером (выбор диска и каталога; создание каталога; создание, просмотр и редактирование текстовых файлов; копирование, перемещение, удаление файлов и каталогов; поиск файлов и каталогов; работа с архивными файлами и т. п.).
Также необходимо отметить, что Norton Commander явился не единственным шагом фирмы Symantec по расширению функциональных возможностей служебного и системного программного обеспечения, работающего в среде DOS. Другой ее известный продукт – Norton Utilities – объединил в себе большое количество утилит, реализующих многие важные и полезные функции, которые затруднительно или даже невозможно осуществить с помощью штатных средств операционной системы.
Следующим шагом в развитии оболочек операционных систем стало появление в 1986 г. графической многооконной операционной оболочки Windows от корпорации Microsoft. В последующие годы она претерпела ряд модификаций и в 1991 г. вышла вepcия Windows 3.1, а несколько позже – сетевой вариант Windows 3.11 (Windows 3.11 For WorkGroups), очень быстро завоевавшие широкое признание пользователей. Windows 3.1 запускалась на выполнение как обычная программа MS-DOS и работала на базе MS-DOS, используя на нижнем уровне внутренние функции и процедуры этой операционной системы. Приципиальным условием для программных приложений, предназначенных для работы в среде Windows, являлось то, что они должны работать с внешними устройствами (монитором, принтером, плоттером и т. п.) не напрямую, а через универсальную систему команд. Управляющая система транслировала вызовы (обращения к тому или иному физическому устройству) и передавала их соответствующему Windows-драйверу данного устройства, который непосредственно отвечал за работу с ним с учетом конкретных особенностей его функционирования. Почти все драйверы устройств Windows 3.1 фактически выполняли функции базовой системы ввода-вывода и работали с устройствами напрямую.
Основой пользовательского интерфейса Windows послужил так называемый графический интерфейс пользователя GUI (Graphical User Interface), разработанном еще в 1960-е годы Дагом Энгельбартом (Doug Engelbart) в научно-исследовательском институте Стэнфорда (Stanford Research Institute) и состоящим из окон, значков, различных меню и мыши. Идеи GUI впервые были использованы в разработках вычислительных машин Xerox PARC, а затем успешно внедрены в качестве пользовательского интерфейса в персональных компьютерах Apple компании Macintosh.
Итак, пользовательский интерфейс Windows 3.1 являлся графическим (использовался графический режим работы видеомонитора) и представлял собой иерархически организованную систему окон и других графических объектов. Интерфейс Windows в отличие от интерфейса командной строки в DOS и псевдографического интерфейса оболочки Norton Commander реализовывал оперативное управление на основе выбора того или иного графически визуализированного элемента (кнопки, пиктограммы, списка и т. п.) с помощью манипулятора мышь (команды клавиатуры, как правило, имели вспомогательное или резервное значение). Основным отличием версии Windows 3.11 была интеграция в программный пакет сетевых драйверов, что позволяло использовать эту версию для работы компьютеров в сети.
Дальнейшим развитием семейства Microsoft Windows стала разработка полноценных операционных систем Windows 95 (Windows 4.0) и Windows NT, положившим начало двух ветвей ОС от Microsoft: Windows 95/98/ME и Windows NT/2000/XP/2003. Более подробная информация об этих системах представлена далее в подразделе 6.3.
Значительную роль в развитии операционных систем играет фирма Novell. Наибольшую известность Novell приобрела благодаря своим сетевым операционным системам семейства NetWare. Эти системы реализованы как системы с выделенными серверами. Основные усилия Novell были затрачены на создание высокоэффективной серверной части сетевой ОС, которая за счет специализации на выполнении функций файл-сервера обеспечивала бы максимально возможную для данного класса ВМ скорость удаленного доступа к файлам и повышенную безопасность данных. Для серверной части своих ОС Novell разработала специализированную операционную систему, оптимизированную на файловые операции и использующую все возможности, предоставляемые процессорами Intel x386 и выше. Для рабочих станций Novell выпустила собственные ОС со встроенными сетевыми функциями: Novell DOS с входящей в нее сетевой одноранговой компонентой Personal Ware, а также ОС UnixWare, являющейся реализацией UNIX System V со встроенными возможности работы в сетях NetWare.
Первая рабочая версия NetWare была выпущена фирмой Novell в 1983 г. В 1993 году фирма Novell выпустила ОС NetWare v.4.0, явившуюся во многих отношениях революционно новым продуктом. Эта система была разработана специально для построения вычислительных сетей «масштаба предприятия» с несколькими файл-серверами, большим количеством сетевых ресурсов и пользователей. Одним из основных нововведений явилась служба каталогов NetWare Directory Services (NDS), хранящая в распределенной по нескольким серверам базе данных информацию обо всех разделяемых сетевых ресурсах и пользователях, что обеспечило возможность при одном логическом входе в систему получать прозрачный доступ ко всем ресурсам многосерверной сети.
NetWare – это специализированная ОС, которая с самого начала проектировалась для оптимизации сетевого сервиса и, в первую очередь, доступа к удаленным файлам. Кроме основной цели разработки семейства ОС NetWare – повышения производительности – ставились также задачи создания открытой, расширяемой и надежной операционной системы, обеспечивающей высокий уровень защиты информации. В 1983 году фирма Novell ввела в систему концепций локальной сети понятия имени пользователя, пароля и характеристики пользователя («профиля пользователя»). Характеристика пользователя содержит перечень ресурсов, к которым пользователь имеет доступ, и права, которыми он обладает при работе с этими ресурсами. Администратор сети может ограничить права пользователя по входу в сеть датой, временем и конкретными рабочими станциями. Средства обнаружения нарушений защиты и блокировки действий нарушителя извещают администратора сети о попытках несанкционированного доступа. Помимо поддержки многопроцессорного режима, в число приоритетных направлений развития NetWare входит обеспечение процессорной независимости.
Операционная система OS/2 v.2.0 корпорации IBM была первой работающей 32-х разрядной ОС для персональных компьютеров. Версия OS/2 Warp, предназначенная для клиентских машин сетей типа клиент-сервер и одноранговых сетей, появилась на рынке раньше Windows 95, позиционированной аналогичным образом. OS/2 поддерживала вытесняющую многозадачность, виртуальную память и виртуальную машину для выполнения DOS-приложений, а также средства объектной ориентации. OS/2 Warp имела хорошо продуманный объектно-ориентированный графический пользовательский интерфейс, а также впервые включала набор средств поддержки сети Internet.
С интенсивным развитием компьютерных сетей в 1990-е годы появились специализированные ОС, которые предназначены исключительно для выполнения коммуникационных задач. Примером такой системы является ОС IOS компании Cisco Systems, которая работает в маршрутизаторах и организует выполнение в мультипрограммном режиме набора программ, реализующих коммуникационные протоколы.
Следует отметить также некоторые ОС, ориентированные на конкретную аппаратную платформу компьютеров, например, MacOS для компьютеров семейства Macintosh, PalmOS и Windows CE (Consumer Electronics – бытовая электроника) для серии сверхминиатюрных так называемых «карманных» компьютеров или PDA (Personal Digital Assistant – персональный цифровой помощник).
Среди операционных систем реального времени заслуженной популярностью пользуются ОС VxWorks и QNX.
Высоким уровнем отказоустойчивости при работе с сетью Internet и интрасетями характеризуются операционные системы SOLARIS фирмы Sun Microsystems. Однако в полной мере высокий уровень отказоустойчивости, обеспечиваемый благодаря сильным сторонам архитектуры ядра системы, может быть реализован только для платформы процессоров SPARC, а аппаратная поддержка платформы Intel ограничена.
6.2. История развития и характеристики
операционных систем UNIX
История операционной системы UNIX началась в 1969 году с совместного проекта Массачусетского технологического института, исследовательской лаборатории Bell Labs и корпорации General Electric – системы MULTICS (Multiplexed Information and Computing Service – информационно-вычислительная служба с мультиплексированием каналов передачи данных). Ее разработчики поставили своей задачей создание большой и сложной системы общего назначения с разделением времени. Лаборатория Bell Labs вскоре вышла из числа участников проекта, после чего один из ее сотрудников, Кен Томпсон (Ken Thompson), к которому затем присоединился Денис Ритчи (Dennis Ritchie), создал усеченный вариант системы MULTICS для миникомпьютера PDP-7. Эта система в шутку была названа UNICS (UNiplexed Information and Computing Service – примитивная информационная и вычислительная служба). В дальнейшем, сохранив то же произношение, система UNICS получила несколько «сокращенное» написание в виде UNIX. UNIX привлекла внимание других специалистов, группа разработчиков увеличилась, и система была перенесена на более современные вычислительные машины PDP-11 (доминирующие в нише миниВМ в 1970-е годы), причем ее переписали на языке программирования высокого уровня С, специально созданном для этой цели Денисом Ритчи. Это событие произошло в 1973 году, когда еще не было принято писать операционные системы на высокоуровневых языках, но время для этого уже пришло, поскольку проблема переносимости системного программного обеспечения между различными аппаратными платформами стояла довольно остро. UNIX обладала огромным преимуществом перед другими ОС – она была переносимой и могла быть установлена, по крайней мере потенциально, на ВМ любой архитектуры.
Поначалу UNIX была сравнительно маленькой, очень простой в использовании и понятной системой. Первая ее версия, однопользовательская, вскоре была расширена и стала поддерживать многопользовательский доступ. Разработчики стремились максимально упростить структуру операционной системы, пусть даже за счет снижения эффективности работы и удаления некоторых функций, которыми на то время обладало большинство подобных систем. UNIX быстро приобрела популярность не только в Bell Labs, но и за ее пределами. Корпорация AT&T (учредитель лаборатории Bell Labs) стала вкладывать средства в развитие UNIX, в результате чего было выпущено несколько новых версий ОС, архитектура которых все более усложнялась. Конечным результатом усилий корпорации AT&T стал продукт под названием System V, развитие которого затем было продолжено уже другими компаниями.
Параллельно с указанной ветвью операционной системы UNIX специалисты Калифорнийского университета в Беркли разрабатывали еще одну, названную BSD (Berkeley Software Distribution – программное изделие Калифорнийского университета). Она тоже получила широкое распространение, а впоследствии на основе обеих ветвей был создан ряд новых версий ОС.
Классической UNIX принято считать так называемую седьмую версию ОС, которая является исходной точкой двух основных ветвей развития данной архитектуры: System V и BSD.
Третья самостоятельная ветвь развития UNIX началась с попытки вернуться к исходному свойству этой операционной системы – предельной простоте. Данная ветвь начинается с микроядерной системы MINIX, за которой последовала значительно более мощная система Linux, разработанная Линусом Торвальдсом (Linus Torvalds) и представленная им в 1991 г. в качестве первой официальной версии 0.02. В настоящее время Linux – это полноценная многозадачная многопользовательская операционная система семейства UNIX. Одним из наиболее удачных вариантов реализации Linux является дистрибутивный комплект Red Hat Linux. Главными особенностями, выделяющими его на фоне других версий Linux, являются, во-первых, наличие средств управления пакетами (Red Hat Package Manager, RPM), служащих для установки программ, проверки их целостности, обновления и удаления программного обеспечения, а во-вторых, наличие графической панели управления (Control panel), с помощью которой можно осуществлять контроль практически за всеми ресурсами ВМ.
Для совместимости различных версий операционной системы UNIX и производных от нее систем Международный институт инженеров по электротехнике и электронике IEEE разработал стандарт системы UNIX, называемый POSIX, который теперь поддерживают большинство версий UNIX. Стандарт POSIX определяет минимальный интерфейс системного вызова, необходимый для совместимости UNIX-систем. Некоторые другие операционные системы в настоящее время тоже поддерживают интерфейс POSIX.
На сегодняшний день существуют версии UNIX для многих ВМ – от персональных компьютеров до суперВМ. Независимо от версии, общими для UNIX чертами являются:
– многопользовательский режим со средствами защиты данных от несанкционированного доступа,
– реализация мультипрограммного режима разделения времени, основанного на использовании алгоритмов вытесняющей многозадачности,
– использование механизмов виртуальной памяти и свопинга,
– унификация операций ввода-вывода на основе расширенного использования понятия «файл»,
– иерархическая файловая система, образующая единое дерево каталогов независимо от количества физических устройств, используемых для размещения файлов,
– переносимость системы за счет написания ее основной части на языке С,
– разнообразные средства взаимодействия процессов, в том числе и через сеть,
– кэширование диска для уменьшения среднего времени доступа к файлам.
Хотя многие пользователи UNIX, особенно опытные программисты, предпочитают командный интерфейс графическому, почти все UNIX-системы поддерживают оконную систему, созданную в Массачусетсском технологическом институте. Она называется X Windows. Эта система оперирует основными функциями окна, позволяя пользователю создавать, удалять, перемещать окна и изменять их размеры с помощью мыши. Часто поверх системы X Windows может быть установлен полный графический интерфейс, например Motif, придающий системе UNIX внешний вид системы типа Microsoft Windows или системы компьютеров Macintosh.
6.3. История развития и характеристики
операционных систем семейства Windows
Особое значение в истории и сегодняшнем дне операционных систем имеет семейство продуктов Windows корпорации Microsoft как наиболее популярных ОС для персональных компьютеров и сетей на их основе.
Как уже отмечалось выше, вплоть до версий Windows 3.1/3.11 это была не операционная система в полном смысле данного понятия, а лишь графическая оболочка, надстройка над ОС MS-DOS. Полноценной ОС Windows стала начиная с четвертой версии, получившей наименование Windows 95. Ключевыми позициями, отличающими Windows 95 от Windows 3.х, явились следующие:
– новое 32-разрядное ядро;
– усовершенствованный механизм многозадачности;
– улучшенная поддержка аппаратного обеспечения;
– новые и существенно обновленные приложения.
После Windows 95 на рынке появилась ее новая редакция Windows 95 OSR2 (OEM Service Release – «сервисный выпуск для производителей компьютеров»). В эту редакцию были включены следующие чрезвычайно полезные дополнения:
– новая файловая система FAT32;
– встроенный браузер-обозреватель Internet Explorer 3.0;
– поддержка трехмерной графики;
– расширенный состав драйверов;
– повышенная стабильность работы системы.
Следующей версией стала Windows 98. Главным достоинством новой системы явилось включение более мощного браузера Internet Explorer 4.0 и обеспечение поддержки новых аппаратных устройств. Дальнейшим совершенствованием стала разработка Windows 98 SE (Second Edition), в которой была расширена поддержка аппаратных устройств с новыми интерфейсами USB и FireWire, включена новая версия браузера Internet Explorer 5.0, а также исправлены некоторые ошибки, добавлены новые функции и в целом существенно повышена стабильность работы.
Последней ОС в ряду Windows 9.х стала Windows ME (Millennium Edition). В нее включены новая система восстановления ОС, встроенный редактор видео, новый Internet Explorer 5.5. В Windows ME значительно обновлен графический интерфейс и упрощена работа с драйверами.
Параллельно с развитием линии ОС Windows 9.х корпорация Microsoft в 1988 году начала разработку и непрерывно продолжает развивать линию принципиально отличающихся от Windows 9.х операционных систем «новой технологии» – Windows NT (NT – New Technology). Если при создании Windows 9.х разработчики стремились сочетать новые возможности с предельной простотой установки и конфигурирования, максимальной совместимостью с имеющимся программным и аппаратным обеспечением, то серия NT прежде всего предназначалась для больших сетей и должна была обеспечить максимальную надежность и безопасность.
Команду разработчиков новой операционной системы возглавил перешедший в Microsoft из Digital Equipment Corporation Дэйв Катлер (Dave Cutler), ранее уже участвовавший в разработке нескольких ОС. К тому времени уже был накоплен немалый опыт академических исследований в области операционных систем, в том числе на основе Mach и других микроядерных архитектур. Результатом трудов команды из почти 40 разработчиков стало появление в 1993 году операционной системы, получившей название Windows NT и поддерживающей процессоры Intel x86, MIPS и Digital Alpha. Годом позже вышла версия Windows NT 3.51 с повышенной производительностью и поддержкой процессора PowerPC. За ней в 1996 последовала Windows NT 4.0.
Windows NT является 32-х разрядной ОС с приоритетной многозадачностью. В качестве фундаментальных компонентов в состав этой ОС входят развитый сетевой сервис и средства обеспечения безопасности. Windows NT обеспечивает совместимость со многими другими операционными и файловыми системами, а также с разнородными сетями, поддерживает высокопроизводительные многопроцессорные вычислительные комплексы. Windows NT не является дальнейшим развитием ранее существовавших продуктов. Ее архитектура создавалась заново с учетом современных жестких требований совместимости, переносимости, масштабируемости, распределенной обработки данных, расширяемости, надежности и отказоустойчивости операционных систем.
Несмотря на сходный интерфейс, Windows NT 4.0. имеет массу отличий от современной ей Windows 95:
– принципиально другое ядро, которое загружается самостоятельно и не имеет в своей основе MS-DOS;
– собственная файловая система NTFS, обеспечивающая разграничение доступа на уровне файлов, протоколирование файловых операций, хранение сверхбольших объемов данных, сжатие дисков и прочее;
– иной механизм многозадачности, обеспечивающий лучшую изоляцию приложений друг от друга и от ядра системы (в частности, драйверы устройств здесь не допускаются к ядру ОС, поэтому принципы написания драйверов для семейств 9.х и NT сильно отличаются);
– существенно расширенные многопользовательские возможности, чему способствует наличие серьезных средств авторизации, защиты трафика и т.п;
– высокая степень масштабируемости.
На смену версии Windows NT 4.0. пришла ОС Windows 2000 Professional (в бета-версиях она называлась Windows NT 5.0.), с которой началась новая схема именования версий системы.
Windows 2000 Professional позволяет:
1. Облегчить использование ОС корпоративными клиентами, что достигается благодаря привычному, но более простому и «интеллектуальному» интерфейсу, упрощению настройки системы путем использованию новых «программ-мастеров», ориентацией на работу с мобильными компьютерами, наличию эффективных встроенных инструментов для работы с Интернет.
2. Сохранить традиционные достоинства систем Windows NT: защищенность информации, устойчивость работы, надежность и высокую производительность.
3. Перенести в систему лучшие качества Windows 98, такие как поддержка существующих приложений и драйверов, поддержка аппаратных устройств нового поколения, встроенная сетевая поддержка для подключения к системам Windows NT Server, Novell NetWare и UNIX.
4. Создать легко конфигурируемую настольную систему с автоматизированным процессом инсталляции, развитыми средствами удаленного администрирования, установки и удаления программ, встроенной диагностики процесса загрузки.
Серверной версией Windows 2000 Professional является система Windows 2000 Server. Эта серверная платформа способна функционировать как сервер файлов, печати, приложений или Web-сервер и по сравнению с Windows 2000 Professional включает множество дополнительных специальных функций.
В конце 2001 г. корпорация Microsoft выпустила новую версию ОС – Windows XP, продолжившую линию Windows NT (внутренняя «фирменная» нумерация новой версии – Windows NT 5.1) и по сути являющейся модифицированной ОС Windows 2000 Professional. В новой ОС радикально изменен графический интерфейс, существенно повышена стабильность системы, значительно усовершенствована процедура инсталляции, усилена аппаратная и программная совместимость.
Новая серверная версия системы Windows 2000 Server – ОС Windows Server 2003 (внутренняя «фирменная» нумерация этой версии – Windows NT 5.2). Windows Server 2003 обладает рядом преимуществ по сравнению с Windows 2000 Server. Это самая быстрая, самая надежная и наиболее защищенная из всех серверных ОС Windows, когда-либо выпущенных Microsoft.
Windows Server 2003 предоставляет интегрированную инфраструктуру, помогающую гарантировать безопасность информации. Надежность, готовность и масштабируемость этой ОС позволяют реализовать сетевую инфраструктуру, соответствующую потребностям наиболее взыскательных пользователей. Windows Server 2003 предоставляет инструменты для развертывания, управления и использования сетевой инфраструктуры предприятия, средства реализации административной политики, автоматизации задач и упрощения процесса модернизации. Новые средства ОС помогают снизить расходы на сопровождение, позволяя пользователям выполнять большее число задач самостоятельно. Windows Server 2003 помогает организовать инфраструктуру прикладных задач и обеспечивает лучшее взаимодействие между системами и клиентами. Для этого ОС предоставляет интегрированные Web-сервер и сервер мультимедийных потоков, которые позволяют легко, быстро и безопасно создавать динамичные Web-сайты для интрасети и Интернета. ОС также включает интегрированный сервер приложений, обеспечивающий легкость разработки, развертывания и управления Web-сервисами.
Высокая надежность Windows Server 2003 позволяет управлять расходами, снижая время ремонтных работ и регламентных простоев. Windows Server 2003 может гибко масштабироваться вверх и вширь в зависимости от текущих потребностей. Инструменты администрирования и настройки Windows Server 2003 упрощают развертывание и управление. Обеспечивается совместимость с существующими приложениями и продуктами независимых производителей.
Резюме
Прообразом современных операционных систем являются разработанные в середине 1950-х годов системы пакетной обработки, которые просто автоматизировали запуск одной программ за другой, а последовательность подлежащих выполнению программ при этом составляла так называемый пакет заданий. Системы пакетной обработки стали первыми системными программами, предназначенными для управления вычислительным процессом.
Следующим этапом эволюции ОС стала разработка в 1960-х годах универсальных ОС, которые были способны работать на разных типах ВМ, имеющих различный набор периферийных устройств и используемых в разных областях человеческой деятельности. Попытки удовлетворения сложных и часто противоречивых требований приводили к тому, что такие ОС были чрезвычайно громоздкими и имели низкую надежность при эксплуатации. Однако, несмотря на указанные проблемы, операционная система OS/360 и другие ей подобные ОС получили широкое признание потребителей. Важнейшим достижением ОС этого периода явилась реализация мультипрограммного режима и спулинга.
Следующий период в эволюции операционных систем связан с появлением в 1980-х годах ВМ на больших интегральных схем. ВМ стали доступны отдельным небольшим организациям и учреждениям, а впервые предложенные в то время «персональные компьютеры» были доступны уже отдельному человеку. ВМ все чаще объдинялись в распределенные вычислительные сети. Такие ВМ и сети на их основе стали широко использоваться неспециалистами, что потребовало разработки «дружественного» программного поддержки сетевого взаимодействия. На рынке операционных систем в то время начали доминировать системы двух классов: многопользовательские многозадачные (мультипрограммные) ОС клона UNIX и однопользовательские однозадачные (однопрограммные) ОС клона MS-DOS.
ОС UNIX получила несколько ветвей развития исходной архитектуры. Это ОС System V (корпорации AT&T) и BSD (Калифорнийского университета в Беркли). Впоследствии на основе обеих ветвей был создан ряд новых версий ОС UNIX. Третья самостоятельная ветвь развития UNIX начиналась с микроядерной системы MINIX, за которой в 1991 году последовала значительно более мощная многозадачная многопользовательская ОС LINUX.
В настоящее время существуют версии ОС UNIX для многих типов ВМ. Независимо от версии, общими для UNIX чертами являются многопользовательский режим со средствами защиты данных от несанкционированного доступа, реализация мультипрограммного режима разделения времени с вытесняющей многозадачностью, использование механизмов виртуальной памяти и свопинга, унификация операций ввода-вывода на основе расширенного использования понятия «файл», иерархическая файловая система, хорошая переносимость системы и множество других свойств.
Операционные системы корпорации Microsoft под названием MS-DOS и их аналоги других корпораций были разработаны для персональных компьютеров клона IBM PC. Управление компьютером при помощи команд DOS, вводимых в режиме командной строки, требует определенных знаний, большой аккуратности и внимания. Для того, чтобы сделать общение с компьютером более простым, были предложены так называемые программы-оболочки, представляющие собой программные надстройки операционной системы, позволяющие пользователю осуществлять действия по управлению ресурсами компьютера в рамках более развитого и удобного, чем командная строка, псевдографического интерфейса,. Следующим историческим шагом в развитии оболочек операционных систем стало появление в 1986 г. графической многооконной операционной оболочки Windows от корпорации Microsoft, которая работала на базе MS-DOS, а основой пользовательского интерфейса Windows послужил графический интерфейс пользователя GUI, представляющий собой в данном случае иерархически организованную систему окон и других графических объектов. Дальнейшим развитием семейства Microsoft Windows стала разработка полноценных операционных систем Windows 95 (Windows 4.0) и Windows NT, положившим начало двух ветвей ОС от Microsoft: Windows 95/98/ME и Windows NT/2000/XP/2003.
Полноценной ОС Windows стала начиная с четвертой версии, получившей наименование Windows 95. Ключевыми позициями, отличающими Windows 95 от Windows 3.х, явились новое 32-разрядное ядро, усовершенствованный механизм многозадачности, улучшенная поддержка аппаратного обеспечения, новые и существенно обновленные приложения. Следующими версиями стали Windows 98, Windows 98 SE и Windows ME. Главными достоинствами новых систем явилось включение более мощных версий браузера Internet Explorer, расширение поддержки новых аппаратных устройств с новыми интерфейсами.
Параллельно с развитием линии ОС Windows 9.х корпорация Microsoft в 1988 году начала разработку и непрерывно продолжает развивать линию принципиально отличающихся от Windows 9.х операционных систем «новой технологии» – Windows NT (NT – New Technology). Windows NT является 32-х разрядной ОС с приоритетной многозадачностью. В качестве фундаментальных компонентов в состав этой ОС входят развитый сетевой сервис и средства обеспечения безопасности. Windows NT совместима со многими другими операционными и файловыми системами, а также с разнородными сетями, поддерживает работу высокопроизводительных многопроцессорных вычислительных комплексов.
На смену версии Windows NT 4.0. пришла существенно усовершенствованная и усиленная ОС Windows 2000 Professional. Серверной версией Windows 2000 Professional является система Windows 2000 Server, включающаяет множество дополнительных специальных функций.
В конце 2001 г. корпорация Microsoft выпустила новую версию ОС – Windows XP, продолжившую линию Windows NT и по сути являющейся модифицированной ОС Windows 2000 Professional. Новая серверная версия системы Windows Server 2003 обладает рядом преимуществ по сравнению с Windows 2000 Server. Это самая быстрая, самая надежная и наиболее защищенная из всех серверных ОС Windows, выпущенных Microsoft до настоящего времени.
Значительную роль в развитии ОС играет фирма Novell со своим сетевым операционными системами семейства NetWare.
Историческое значение имеет ОС OS/2 корпорации IBM, которая появилась на рынке раньше Windows 95 и была первой работающей 32-х разрядной ОС для персональных компьютеров, а кроме того поддерживала вытесняющую многозадачность, виртуальную память и имела средства работы в сети Internet.
Следует отметить также некоторые специализированные ОС. Например, IOS компании Cisco Systems предназначена исключительно для выполнения коммуникационных задач, MacOS ориентирована на конкретную аппаратную платформу компьютеров семейства Macintosh, PalmOS и Windows CE работают в сверхминиатюрных так называемых «карманных» компьютерах.
Отметим также ОС Solaris фирмы Sun Microsystems, которая благодаря высокому уровню отказоустойчивости предпочтительна для использования в интер- и интрасетях.
Контрольные вопросы и задания
1. Охарактеризуйте начальные этапы разработки и развития ОС.
2. Опишите основные характерные особенности ОС семейства MS-DOS и историю их эволюции.
3. Какие функции выполняют операционные оболочки, какова их роль в совершенствовании пользовательского интерфейса ОС?
4. Дайте характеристику ОС семейства UNIX, представьте области практического применения наиболее популярных версий UNIX.
5. В чем особенности реализации и функционирования сетевых операционных систем компании Novell?
6. Охарактеризуйте ОС семейства Windows 95/98/ME.
7. Назовите главные достоинства ОС линии Windows NT.
8. Какие качества характерны для современных серверных версий ОС Windows?
9. Перечислите известные специализированные ОС.
7. Пример практической реализации
операционной системы: UNIX
7.1. Обзор системы UNIX
7.1.1. Общие представления
Операционная система UNIX представляет собой интерактивную систему, разработанную для одновременной поддержки нескольких процессов и нескольких пользователей. Она была разработана программистами и для программистов, чтобы использовать ее в окружении, в котором большинство пользователей являются относительно опытными и занимаются сложными проектами разработки программного обеспечения. Во многих случаях большое количество программистов активно сотрудничают в деле создания единой системы, поэтому в операционной системе UNIX есть достаточное количество средств, позволяющих программистам работать вместе и управлять совместным использованием общей информации. К настоящему времени существует множество версий системы UNIX (см. раздел 6) и между ними имеются определенные различия. В дальнейшем изложении основное внимание уделяется общим чертам всех версий, а не особенностям какой-либо конкретной версии. Поэтому рассматриваемые вопросы реализации ОС UNIX не всегда в равной степени соответствуют разным версиям.
7.1.2. Интерфейсы системы UNIX
Операционную систему UNIX можно рассматривать в виде некоторой пирамиды. У основания пирамиды располагается аппаратное обеспечение, состоящее из центрального процессора, памяти, дисков, терминалов и других устройств. Выше над аппаратным обеспечением работает операционная система UNIX. Ее функции заключаются в управлении аппаратным обеспечением и предоставлении всем программам интерфейса системных вызовов. Эти системные вызовы позволяют программам создавать процессы, файлы и прочие ресурсы, а также управлять ими. Программы обращаются к системным вызовам, помещая аргументы в регистры центрального процессора (или иногда в стек) и выполняя команду эмулированного прерывания для переключения из пользовательского режима в режим ядра и передачи управления операционной системе UNIX. Системные вызовы реализуются библиотечные функциями – процедурами. Каждая такая процедура помещает аргументы в нужное место и выполняет команду эмулированного прерывания. Интерфейс библиотечных функций определен в стандарте POSIX. Стандарт POSIX определяет библиотечные процедуры, соответствующие системным вызовам, их параметры, что они должны делать и какой результат возвращать.
Помимо операционной системы и библиотеки системных вызовов, все версии UNIX содержат большое количество стандартных программ, некоторые из них описываются стандартом POSIX 1003.2, тогда как другие могут различаться в разных версиях системы UNIX. К этим программам относятся командный процессор (оболочка), компиляторы, редакторы, программы обработки текста и утилиты для работы с файлами. Именно эти программы и запускаются пользователем с терминала.
Таким образом, можно говорить о трех интерфейсах в операционной системе UNIX: интерфейсе системных вызовов, интерфейсе библиотечных функций и интерфейсе, образованным набором стандартных обслуживающих программ.
7.1.3. Оболочка и утилиты системы UNIX
У многих версий системы UNIX имеется графический интерфейс пользователя, схожий с популярными интерфейсами, примененными на компьютере Macintosh и впоследствии в системе Windows. Однако истинные программисты до сих пор предпочитают интерфейс командной строки, называемый оболочкой (shell). Подобный интерфейс значительно быстрее в использовании, существенно мощнее и проще расширяется. Ниже будет кратко описана так называемая оболочка Бурна (sh).
Когда оболочка запускается, она инициализируется, а затем печатает на экране символ приглашения к вводу (обычно это знак доллара или процента) и ждет, когда пользователь введет командную строку. После того как пользователь введет командную строку, оболочка извлекает из нее первое слово и ищет файл с таким именем. Если такой файл удается найти, оболочка запускает его. При этом работа оболочки приостанавливается на время работы запущенной программы. По завершении работы программы оболочка снова печатает приглашение и ждет ввода следующей строки. Здесь важно подчеркнуть, что оболочка представляет собой обычную пользовательскую программу. Все, что ей нужно, – это способность ввода с терминала и вывода на терминал, а также возможность запускать другие программы.
У команд оболочки могут быть аргументы, которые передаются запускаемой программе в виде текстовых строк. Не все аргументы обязательно должны быть именами файлов. Аргументы, управляющие работой команды или указывающие дополнительные значения, называются флагами или ключами и по соглашению обозначаются знаком тире.
Программа вроде оболочки не должна открывать терминал, чтобы прочитать с него или вывести на него строку. Вместо этого запускаемые программы автоматически получают доступ к файлу, называемому стандартным устройством ввода (standard input), и к файлу, называемому стандартным устройством вывода (standard output), а также к файлу, называемому стандартным устройство для вывода сообщений об ошибках (standard error). По умолчанию всем трем устройствам соответствует терминал, то есть клавиатура для ввода и экран для вывода. Многие программы в системе UNIX читают данные со стандартного устройства ввода и пишут на стандартное устройство вывода. Стандартные ввод и вывод также можно перенаправить, что является очень полезным свойством. Для этого используются символы «<» и «>» соответственно. Разрешается их одновременное использование в одной командной строке. Программа, считывающая данные со стандартного устройства ввода, выполняющая определенную обработку этих данных и записывающая результат в поток стандартного вывода, называется фильтром.
В системе UNIX часто используются командные строки, в которых первая программа в командной строке формирует вывод, используемый второй программой в качестве входа. Система UNIX предоставляет более простой способ реализации этого механизма, который заключается в использовании вертикальной черты, называемой символом канала. Набор команд, соединенных символом канала, называется конвейером и может содержать произвольное количество команд.
UNIX является универсальной многозадачной системой. Один пользователь может одновременно запустить несколько программ, каждую в виде отдельного процесса. Конвейеры также могут выполняться в фоновом режиме. Можно одновременно запустить несколько фоновых конвейеров.
Список команд оболочки может быть помещен в файл, а затем этот файл с командами может быть выполнен, для чего нужно запустить оболочку с этим файлом в качестве входного аргумента. Вторая программа оболочки просто выполнит перечисленные в этом файле команды одну за другой, точно так же, как если бы эти команды вводились с клавиатуры. Файлы, содержащие команды оболочки, называются сценариями оболочки. Сценарии оболочки могут присваивать значения переменным оболочки и затем считывать их. Они также могут запускаться с параметрами. Таким образом, сценарии оболочки представляют собой настоящие программы, написанные на языке оболочки. Существует альтернативная оболочка Berkley С, разработанная таким образом, чтобы сценарии оболочки (и команды языка вообще) выглядели во многих аспектах подобно программам на языке С. Поскольку оболочка представляет собой всего лишь еще одну пользовательскую программу, к настоящему времени написано множество различных ее версий.
Пользовательский интерфейс UNIX состоит не только из оболочки, но также из большого числа стандартных обслуживающих программ, называемых также утилитами. К ним относятся команды управления файлами и каталогами, фильтры, средства разработки программ (такие как текстовые редакторы и компиляторы), текстовые процессоры, программы системного администрирования и другие программы. Стандарт POSIX 1003.2 определяет синтаксис и семантику менее 100 из этих программ, в основном относящихся к первым трем категориям. Идея стандартизации данных программ заключается в том, чтобы можно было писать сценарии оболочки, которые работали бы на всех системах UNIX. Помимо этих стандартных утилит, существует множество других прикладных программ, таких как web-браузеры, программы просмотра изображений и т. д.
7.1.4. Структура ядра системы UNIX
Нижний уровень ядра состоит из драйверов устройств и процедуры диспетчеризации процессов. Все драйверы системы UNIX делятся на два класса: драйверы символьных устройств и драйверы блочных устройств. Основное различие между этими двумя классами устройств заключается в том, что на блочных устройствах разрешается операция поиска, а на символьных нет. Технически сетевые устройства представляют собой символьные устройства, но они обрабатываются по-иному, поэтому их правильнее выделить в отдельный класс. Диспетчеризация процессов производится при возникновении прерывания. При этом низкоуровневая программа останавливает выполнение работающего процесса, сохраняет его состояние в таблице процессов ядра и запускает соответствующий драйвер. Кроме того, диспетчеризация процессов производится также, когда ядро завершает свою работу и наступает время для того, чтобы снова запустить процесс пользователя. Программа диспетчеризации процессов написана на ассемблере и представляет собой отдельную от процедуры планирования программу.
В более высоких уровнях программы, относящиеся к тому или иному уровню могут существенно отличаться друг от друга. Так ко второму снизу уровню относятся программы символьных устройств, драйверы сетевых устройств, драйверы дисковых устройств, программы диспетчиризации процессов.
Сетевое программное обеспечение часто бывает модульным, с поддержкой множества различных устройств и протоколов. Уровень выше сетевых драйверов выполняет своего рода функции маршрутизации, гарантируя, что правильный пакет направляется правильному устройству или блоку управления протоколами. Большинство систем UNIX содержат в своем ядре полноценный маршрутизатор Интернета, и хотя его производительность ниже, чем у аппаратного маршрутизатора, эта программа появилась раньше современных аппаратных маршрутизаторов. Над уровнем маршрутизации располагается стек протоколов, обязательно включая протоколы IP и TCP, но также иногда и некоторые дополнительные протоколы. Над сетевыми протоколами располагается интерфейс сокетов, позволяющий программам создавать сокеты для отдельных сетей и протоколов. Для использования сокетов пользовательские программы получают дескрипторы файлов.
Над дисковыми драйверами располагаются буферный кэш и страничный кэш файловой системы. В ранних системах UNIX буферный кэш представлял собой фиксированную область памяти, а остальная память использовалась для страниц пользователя. Во многих современных системах UNIX этой фиксированной границы уже не существует, и любая страница памяти может быть схвачена для выполнения любой задачи, в зависимости от того, что требуется в данный момент.
Над буферным кэшем располагаются файловые системы. Большинством систем UNIX поддерживаются несколько файловых систем. Все файловые системы совместно используют общий буферный кэш. Выше файловых систем помещается именование файлов, управление каталогами, управление жесткими и символьными связями, а также другие свойства файловой системы, одинаковые для всех файловых систем.
Над страничным кэшем располагается уровень системы виртуальной памяти. В нем реализуется вся логика работы со страницами, например алгоритм замещения страниц. Поверх него находится программа отображения файлов на виртуальную память и высокоуровневая программа управления страничными прерываниями. Эта программа решает, что нужно делать при возникновении страничного прерывания. Сначала она проверяет допустимость обращения к памяти и, если все в порядке, определяет местонахождение требуемой страницы и то, как она может быть получена.
Над диспетчером располагается планировщик процессов, выбирающий процесс, который должен быть запущен следующим. Если потоками управляет ядро, то управление потоками также помещается здесь, хотя в некоторых системах UNIX управление потоками вынесено в пространство пользователя. Над планировщиком расположена программа для обработки сигналов и отправки их в требуемом направлении, а также программа, занимающаяся созданием и завершением процессов.
Верхний уровень представляет собой интерфейс системы. Во-первых, он включает интерфейс системных вызовов. Все системные вызовы поступают сюда и направляются одному из модулей низших уровней в зависимости от природы системного вызова. Во-вторых, интерфейс системы представляет собой вход для аппаратных и эмулированных прерываний, включая сигналы, страничные прерывания, разнообразные исключительные ситуации процессора и прерывания ввода-вывода.
7.2. Процессы в UNIX
7.2.1. Основные понятия
Единственными активными сущностями в системе UNIX являются процессы. Процессы UNIX очень похожи на классические последовательные процессы, которые рассматривались в разделе 1. Каждый процесс запускает одну программу и изначально получает один поток управления. Другими словами, у процесса есть один счетчик команд, указывающий на следующую исполняемую команду процессора. Большинство версий UNIX позволяют процессу после того, как он запущен, создавать дополнительные потоки. UNIX представляет собой многозадачную систему, так что несколько независимых процессов могут работать одновременно. У каждого пользователя может быть одновременно несколько активных процессов, так что в большой системе могут одновременно работать сотни и даже тысячи процессов. Действительно, на большинстве однопользовательских рабочих станций (даже без участия пользователя) работают десятки фоновых процессов, называемых демонами (daemon). Они запускаются автоматически при загрузке системы. Демоны позволяют планировать в системе UNIX активность на минуты, часы, дни и месяцы вперед, управлять входящей и исходящей электронной почтой, очередями на принтер, проверять наличие свободных страниц памяти и т. д. Демоны реализуются в системе UNIX относительно просто, так как каждый из них представляет собой отдельный процесс, независимый ото всех остальных процессов.
В операционной системе UNIX посредством системного вызова fork создается точная копия исходного процесса (так называемого родительского процесса). Новый процесс называется дочерним процессом. У родительского и у дочернего процессов есть свои собственные образы памяти. Если родительский процесс впоследствии изменяет какие-либо свои переменные, изменения остаются невидимыми для дочернего процесса, и наоборот.
Открытые файлы совместно используются родительским и дочерним процессами. Это значит, что если какой-либо файл был открыт до выполнения системного вызова fork, он останется открытым в обоих процессах и в дальнейшем. Изменения, произведенные с этим файлом, будут видимы каждому процессу. Такое поведение является единственно разумным, так как эти изменения будут также видны любому другому процессу, который тоже откроет этот файл.
У родительского процесса может быть много дочерних процессов. Поскольку у дочерних процессов также могут быть дочерние процессы, исходный процесс может создать целое дерево детей, внуков, правнуков и т. д.
В системе UNIX процессы могут общаться друг с другом с помощью разновидности обмена сообщениями. Можно создать канал между двумя процессами, в который один процесс может писать поток байтов, а другой процесс может его читать. Эти каналы иногда называют трубами. Синхронизация процессов достигается путем блокирования процесса при попытке прочитать данные из пустого канала. Когда данные появляются в канале, процесс разблокируется.
Процессы также могут общаться другим способом: при помощи программных прерываний. Один процесс может послать другому так называемый сигнал. Процессы могут сообщить системе, какие действия следует предпринимать, когда придет сигнал. У процесса есть выбор: проигнорировать сигнал, перехватить его или позволить сигналу убить процесс (действие по умолчанию для большинства сигналов). Если процесс выбрал перехват посылаемых ему сигналов, он должен указать процедуры обработки сигналов. Когда сигнал прибывает, управление сразу же передается обработчику. Когда процедура обработки сигнала завершает свою работу, управление снова возвращается в то место процесса, в котором оно находилось, когда пришел сигнал. Обработка сигналов аналогична обработке аппаратных прерываний ввода-вывода. Процесс может посылать сигналы только членам его группы процессов, состоящей из его прямого родителя, всех прародителей, братьев и сестер, а также детей (внуков и правнуков). Процесс может также послать сигнал сразу всей своей группе за один системный вызов.
Сигналы в UNIX используются и для других целей. Например, если процесс выполняет вычисления с плавающей точкой и непреднамеренно делит число на 0, он получает сигнал исключения при выполнении операции с плавающей точкой. Сигналы UNIX описываются стандартом POSIX. В большинстве систем UNIX также имеются дополнительные сигналы, но программы, использующие их, могут оказаться непереносимыми на другие версии UNIX.
В первых версиях системы UNIX понятия потоков не существовало. После введения этого понятия и возможности управления потоками были стандартизированы соответствующие системные вызовы в виде части стандарта POSIX – P1003.1c.
В исходном варианте стандарта POSIX не указывается, должны ли потоки реализовываться в пространстве ядра или в пространстве пользователя. Преимущество потоков в пользовательском пространстве состоит в том, что они легко реализуются без необходимости изменения ядра, а переключение потоков осуществляется очень эффективно. Недостаток потоков в пространстве пользователя заключается в том, что если один из потоков заблокируется (например, на операции ввода-вывода, семафоре или страничном прерывании), все потоки процесса блокируются. Ядро полагает, что существует только один поток, и не передает управление процессу потока, пока блокировка не снимется. Таким образом, системные вызовы, определенные в части стандарта P1003.1c были подобраны так, чтобы потоки могли быть реализованы любым способом. До тех пор, пока пользовательские программы четко придерживаются семантики стандарта POSIX – P1003.1c, оба способа реализации работают корректно. Когда используется системная реализация потоков, они являются настоящими системными вызовами. При использовании потоков на уровне пользователя они полностью реализуются в динамической библиотеке в пространстве пользователя.
Синхронизация потоков может осуществляться при помощи мьютексов. Как правило, мьютекс охраняет какой-либо ресурс, например буфер, совместно используемый двумя потоками. Чтобы гарантировать, что только один поток в каждый момент времени имеет доступ к общему ресурсу, предполагается, что потокиблокируют (захватывают) мьютекс перед обращением к ресурсу и разблокируют (отпускают) его, когда ресурс им более не нужен. До тех пор пока потоки соблюдают данный протокол, состояния состязания можно избежать. Напомним, что название мьютекс (mutex) образовано от английских слов mutual exclusion – взаимное исключение, так как мьютексы подобны двоичным семафорам, то есть семафорам, способным принимать только значения 0 и 1. Таким образом мьютекс может находиться в одном из двух состояний: блокированный и разблокированный. Поток может заблокировать мьютекс с помощью системного вызова. Если мьютекс уже заблокирован, то поток, обратившийся к этому вызову, блокируется. Когда поток, захвативший мьютекс, выполнил свою работу в критической области, он должен освободить мьютекс, обратившись к соответствующему системному вызову.
Мьютексы предназначены для кратковременной блокировки, например для защиты совместно используемой переменной. Они не предназначаются для долговременной синхронизации, например для ожидания, когда освободится накопитель на магнитной ленте. Для долговременной синхронизации применяются так называемые переменные состояния. Переменные состояния используются следующим образом: один поток ждет, когда переменная примет определенное значение, а другой поток сигнализирует ему изменением этой переменной. Например, обнаружив, что нужный ему накопитель на магнитной ленте занят, поток может обратиться к системному вызову, задав в качестве параметра адрес переменной, которую все потоки согласились связать с накопителем на магнитной ленте. Когда поток, использующий накопитель на магнитной ленте, наконец, освободит это устройство, он обращается к соответствующему системному вызову, чтобы изменить переменную состояния и тем самым сообщить ожидающим потокам, что накопитель свободен. Если ни один поток в этот момент не ждет, когда освободится накопитель на магнитной ленте, этот сигнал просто теряется. Другими словами, переменные состояния не считаются семафорами.
7.2.2. Реализация процессов в UNIX
У каждого процесса в системе UNIX есть пользовательская часть, в которой работает программа пользователя. Однако когда один из потоков обращается к системному вызову, происходит эмулированное прерывание с переключением в режим ядра. После этого поток начинает работу в контексте ядра, с отличной картой памяти и полным доступом к ресурсам машины. Это все еще тот же самый поток, но теперь обладающий большей мощью, а также со своим стеком ядра и счетчиком команд в режиме ядра. Это важно, так как системный вызов может блокироваться на полпути, например, ожидая завершения дисковой операции. При этом счетчик команд и регистры будут сохранены таким образом, чтобы позднее поток можно было восстановить в режиме ядра.
Ядро поддерживает две ключевые структуры данных, относящиеся к процессам: таблицу процессов и структуру пользователя. Таблица процессов является резидентной. В ней содержится информация, необходимая для всех процессов, даже для тех процессов, которых в данный момент нет в памяти. Структура пользователя выгружается на диск, освобождая место в памяти, когда относящийся к ней процесс отсутствует в памяти, чтобы не тратить память на ненужную в данный момент информацию.
Информация в таблице процессов подразделяется на следующие категории:
1. Параметры планирования. Приоритеты процессов, процес-сорное время, потребленное за последний учитываемый период, количество времени, проведенное процессом в режиме ожидания. Вся эта информация используется для выбора процесса, которому будет передано управление следующим.
2. Образ памяти. Указатели на сегменты программы, данных и стека, или, если используется страничная организация памяти, указатели на соответствующие им таблицы страниц. Если программный сегмент используется совместно, то программный указатель указывает на общую таблицу программы. Когда процесса нет в памяти, то здесь также содержится информация о том, как найти части процесса на диске.
3. Сигналы. Маски, указывающие, какие сигналы игнорируются, какие перехватываются, какие временно заблокированы, а какие находятся в процессе доставки.
4. Прочая информация. Текущее состояние процесса, ожидаемые процессом события (если таковые есть), идентификатор текущего процесса, идентификатор родительского процесса, идентификаторы пользователя и группы, а также некоторая другая информация.
В структуре пользователя содержится информация, которая не требуется, когда процесса физически нет в памяти и он не выполняется. Например, хотя процессу, выгруженному на диск, можно послать сигнал, выгруженный процесс не может прочитать файл. По этой причине информация о сигналах должна храниться в таблице процессов, постоянно находящейся в памяти, даже когда процесс не присутствует в памяти. С другой стороны, сведения об описателях файлов могут храниться в структуре пользователя и загружаться в память вместе с процессом.
Данные, хранящиеся в структуре пользователя, включают в себя следующие пункты:
1. Машинные регистры. Когда происходит прерывание с пере-ключением в режим ядра, машинные регистры (включая регистры с плавающей точкой) сохраняются здесь.
2. Состояние системного вызова. Информация о текущем системном вызове, включая параметры и результаты.
3. Таблица дескрипторов файлов. Когда происходит обращение к системному вызову, работающему с файлом, дескриптор файла используется в качестве индекса в данной таблице, что позволяет найти структуру данных (i-узел), соответствующую данному файлу.
4. Учетная информация. Указатель на таблицу, учитывающую процессорное время, использованное процессом в пользовательском и системном режимах. В некоторых системах здесь также ограничивается процессорное время, которое может использовать процесс, максимальный размер стека, количество страниц памяти и так далее.
5. Стек ядра. Фиксированный стек для использования процессом в режиме ядра.
Рассмотрим подробне, как в системе UNIX создаются процессы. Когда выполняется системный вызов fork, вызывающий процесс обращается в ядро и ищет свободную ячейку в таблице процессов, в которую можно записать данные о дочернем процессе. Если свободная ячейка находится, системный вызов копирует туда информацию из ячейки родительского процесса. Затем он выделяет память для сегментов данных и для стека дочернего процесса, куда копируются соответствующие сегменты родительского процесса. Структура пользователя (которая часто хранится вместе с сегментом стека) копируется вместе со стеком. Программный сегмент может либо копироваться, либо использоваться совместно, если он доступен только для чтения. Начиная с этого момента дочерний процесс может быть запущен.
Для дочернего процесса создается новая ячейка в таблице процессов, которая заполняется по большей мере из соответствующей ячейки родительского процесса. Дочерний процесс получает идентификатор, затем настраивается его карта памяти. Кроме того, дочернему процессу предоставляется совместный доступ к файлам родительского процесса. Затем настраиваются регистры дочернего процесса, после чего он готов к запуску.
Так как никакая область памяти не может использоваться совместно родительским и дочерним процессами, дочернему процессу выделяются новые таблицы страниц, но эти таблицы указывают на страницы родительского процесса, помеченные как доступные только для чтения. Когда дочерний процесс пытается писать в такую страницу, происходит прерывание. При этом ядро выделяет дочернему процессу новую копию этой страницы, к которой этот процесс получает также и доступ записи. Таким образом, копируются только те страницы, в которые дочерний процесс пишет новые данные. Такой механизм называется копированием при записи. При этом сохраняется память, так как страницы с программой не копируются.
После того, как дочерний процесс начинает работу, его программа выполняет системный вызов ехес, задавая имя команды в качестве параметра. При этом ядро находит и проверяет исполняемый файл, копирует в ядро аргументы и строки окружения, а также освобождает старое адресное пространство и его таблицы страниц.
Затем следует создать и заполнить новое адресное пространство. Если системой поддерживается отображение файлов на адресное пространство памяти, как, например, в System V, BSD и в большинстве других версий UNIX, то таблицы страниц настраиваются следующим образом: в них указывается, что страниц в памяти нет, кроме, возможно, одной страницы со стеком, а содержимое адресного пространства может подгружаться из исполняемого файла на диске. Когда новый процесс начинает работу, он немедленно вызывает страничное прерывание, в результате которого первая страница программы подгружается с диска. Таким образом, ничего не нужно загружать заранее, что позволяет быстро запускать программы, а в память загружать только те страницы, которые действительно нужны программам. Наконец, в стек копируются аргументы и строки окружения, сигналы сбрасываются, а все регистры устанавливаются на ноль. С этого момента новая команда начинает исполнение.
Реализация потоков зависит от того, поддерживаются они ядром или нет. Если потоки ядром не поддерживаются, как, например, в 4BSD, реализация потоков целиком осуществляется в библиотеке, загружающейся в пространстве пользователя.
7.2.3. Планирование в системе UNIX