Принципы построения системных и прикладных программных интерфейсов

 

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

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. Если говорить о переносимости исходного кода, то здесь существует только одно требование – используемая внешняя библиотека должна быть доступна в любой из архитек­тур, на которые ориентирована прикладная программа. Тогда удается достигнуть переносимости. Это возможно, если используемая биб­лиотека удовлетворяет какому-то принятому стандарту, а система программиро­вания поддерживает этот стандарт.