Вопрос №5. Архитектура многозадачных операционных систем
Все ОС строятся по модульному принципу (планирование процессов, управление памятью, подсистема ввода/вывода и т.д.), и для них очень важны способы взаимодействия между модулями (межмодульный интерфейс). Модульный состав и организация межмодульного взаимодействия и составляют архитектуру ОС.
Первой из четко сформулированных архитектурных концепций ОС является иерархия абстрактных машин. Самый нижний уровень иерархии составляет реальная машина с ее интерфейсом оборудования. Нижний слой программного обеспечения составляет первый уровень. Совместно с аппаратными средствами он представляет некоторую абстрактную машину со своим, более высокоуровневым интерфейсом оборудования. На основе этого интерфейса строится абстрактная машина второго уровня и т.д. Последовательным наращиванием слоев программного обеспечения интерфейс абстрактной машины доводится до уровня интерфейса процессов.
Следующей архитектурной концепцией является концепция ОС виртуальных машин. В ОС виртуальных машин интерфейс процесса выглядит как интерфейс оборудования. В предельном случае внешние формы этих двух интерфейсов совпадают полностью. В этом случае процессу доступны все команды из набора команд вычислительной системы. Но на самом деле выдача процессом привилегированной команды вызывает прерывание-ловушку. Обрабатывая ловушку, ОС выполняет для процесса требуемую команду или моделирует выполнение этой команды на виртуальном оборудовании. У процесса создается иллюзия, что в его полном распоряжении находится реальная вычислительная система.
Концепция микроядра подразумевает наличие «мини-ОС», реализующей наиболее фундаментальные, критичные по времени и аппаратно-зависимые функции управления, чаще всего это: управление реальной памятью, переключение процессов, средства обмена сообщениями между процессами, а в мультипроцессорных системах – и управление загрузкой процессоров. Концепция микроядра предполагает оформление модулей ОС в виде процессов.
В объектно-ориентированных ОС ресурсы представляются в виде объектов – полностью инкапсулированных структур данных. Для каждого типа объектов определен набор допустимых операций над ним. Такие ОС позволяют обеспечить надежную защиту системных и пользовательских ресурсов.
Реальные ОС, как правило, сочетают в себе комбинацию различных архитектурных подходов.
Вопрос №6. Ядро многозадачных операционных систем.
Все современные ОС предполагают выполнение программных задач на аппаратной платформе, обеспечивающей по крайней мере 2 режима функционирования процессора:
– Режим ядра (супервизора) – в котором программа может выполнять все команды процессора
– Режим процесса (задачи) – программа может выполнять лишь некоторое подмножество команд, в которое не входят команды управления системой.
Под процессом подразумевается загруженная в память и готовая к исполнению программа.
Та часть ОС, которая работает в режиме ядра, так и называется ядром. Процессы пользователей работают в режиме процесса. Большая (количественно) часть модулей ОС также работает в режиме процесса.
На ядро, как правило, возлагаются такие основные функции:
– обработка прерываний;
– создание и уничтожение процессов;
– переключение процессов из одного состояния в другое;
– синхронизация и взаимодействие процессов;
– поддержка операций ввода-вывода;
– поддержка файловой системы;
– учет работы системы и использования ресурсов пользователями;
Для ОС процесс представляется блоком контекста процесса. Блок контекста содержит информацию о процессе, необходимую для ОС, в том числе информацию обо всех выделенных процессу ресурсах. Действия ОС по управлению процессами сводятся к манипуляциям с блоками контекста процессов и с отдельными полями этих блоков. Процесс в системе может находиться в трех различных состояниях, представленных на рис. 2.
Рис 2. Виды состояний процесса
– Активное состояние - процесс имеет все необходимые для выполнения ресурсы, в том числе и ресурс центрального процессора. Активный процесс выполняется.
– Готовое состояние - процесс имеет все необходимые для выполнения ресурсы, кроме ресурса процессора.
– Заблокированное (ожидающее) состояние - процессу не хватает еще какого-либо ресурса (ресурсов).
Процесс, поступивший в систему, создается в заблокированном состоянии, пока ему не будут выделены необходимые ресурсы. Получив ресурсы, процесс попадает в очередь готовых процессов, где и ожидает, когда ему будет выделен процессор. Процесс, получивший процессор, становится активным и выполняется. Активный процесс переходит в блокированное состояние, когда выдает системный вызов - запрос на ресурсы, которые не могут быть ему предоставлены немедленно (например, выполнение операции ввода-вывода). При этом процесс попадает в очередь к тому ресурсу, который он запрашивает. Процесс может перейти из активного состояния в готовое либо по собственной инициативе, добровольно отказавшись от использования центрального процессора, либо по инициативе ОС.
Вопрос №7. Лексический анализатор, назначение, проблема определения границ лексем
Лексический анализатор – это часть компилятора, которая читает литеры программы на исходном языке и строит из них слова (лексемы) исходного языка. На вход лексического анализатора поступает текст исходной программы, а выходная информация передается для дальнейшей обработки компилятором на этапе синтаксического анализа и разбора.
Лексема– это структурная единица языка, которая состоит из элементарных символов языка и не содержит в своем составе других структурных единиц языка. Лексемами языков программирования являются идентификаторы, константы, ключевые слова языка, знаки операций и т. п. Состав возможных лексем каждого конкретного языка программирования определяется синтаксисом этого языка.
Лексические анализаторы выполняют исключение из текста исходной программы комментариев и незначащих пробелов, а также выделение лексем следующих типов: идентификаторов, строковых, символьных и числовых констант, знаков операций, разделителей и ключевых (служебных) слов входного языка.
Проблема определения границ лексем
Для многих языков программирования информации на этапе лексического анализа может быть недостаточно для однозначного определения типа и границ очередной лексемы. В этом случае лексический анализ исходного текста должен выполняться поэтапно. Как известно, в состав компилятора входят синтаксические и лексические анализаторы. Лексический и синтаксический анализаторы функционируют параллельно, поочередно обращаясь друг к другу. Лексический анализатор, найдя очередную лексему, передает ее синтаксическому анализатору, тот пытается выполнить анализ считанной части исходной программы и может либо запросить у лексического анализатора следующую лексему, либо потребовать от него вернуться на несколько шагов назад и попробовать выделить лексемы с другими границами. При этом он может сообщить информацию о том, какую лексему следует ожидать.
Чтобы избежать параллельной работы лексического и синтаксического анализаторов, так как это требует больше вычислительных ресурсов и в общем случае большего времени на анализ исходной программы, разработчики компиляторов и языков программирования часто идут на разумные ограничения синтаксиса входного языка. Например, для языка С++ принято соглашение, что при возникновении проблем с определением границ лексемы всегда выбирается лексем максимально возможной длины.