Общая проблема стандартов типа POSIX состоит в том, что они никогда не становятся законченными, и стадия определения такого стандарта занимает многие годы. В такой ситуации разработчики приложений часто берут дело в свои руки. В 1993 году группа разработчиков приложений для Unix и производителей Unix-подобных операционных систем решила определить свой собственный набор API. Они не могли ждать, пока спецификация POSIX «созреет» до такой степени, чтобы ее можно было использовать. Кроме того, ясно, что когда спецификация POSIX будет, наконец, полностью завершена, все приложения придется переписывать под новый стандарт.
Вместо этого, упомянутая группа разработчиков выделила все API, которые используются в настоящее время наиболее популярными приложениями для Unix. Из тысяч существующих Unix-приложений они взяли 50 самых распространенных и выбрали 1179 функций API в качестве основы нового стандарта, который первоначально был назван SPEC1170. Позднее это название было заменено на «Единая Спецификация UNIX» (Single UNIX Specification), и данный стандарт становится теперь новой промышленной спецификацией Unix. Помимо указанных API в него входит часть интерфейсов POSIX. В состав спецификации продолжают включаться новые API.
Очевидная проблема во всей этой работе по определению API была лаконично сформулирована одним из сотрудников института NIST (National Institute of Standards and Technology Национального института стандартов и технологий США): «Самое милое в стандартах — это большой их выбор». В самом деле, множество противоречащих друг другу и быстро изменяющихся стандартов делает невозможным создание приложения, которое было бы переносимо на все платформы. Далее, в главе 11, мы рассмотрим язык программирования Java и предоставляемые им возможности по созданию переносимых приложений.
Более того, эти стандарты не являются полными, то есть во многих случаях приложениям приходится действовать «в обход» API. В результате приложение становится зависимым от аппаратуры и программного обеспечения нижних уровней: в тот момент, когда приложение обходит API, все проблемы, присущие процессоро-ори-ентированным архитектурам, возникают снова.
Машинная архитектура высокого уровня
Истинная независимость от аппаратуры может быть достигнута, если вместо определения отдельных API для разных специфических приложений (что имеет место в случае такой API-ориентированной архитектуры как Single Unix Specification), будет формально определен общий интерфейс для всех приложений. Более того, если в такой интерфейс заложены возможности расширения, то в любое время для достижения переносимости приложений к нему могут быть добавлены API Single UNIX Specification. Именно такой подход лежит в основе архитектуры AS/400, которая определяет законченный набор API для всех приложений и не позволяет последним обходить API.
Независимый от технологии машинный интерфейс (Technology-Independent Machine Interface), который часто называют просто MI [ 9 ] Недавно, название этого интерфейса стали сокращать как TIMI. Мне не слишком нравится имя "Тимми" (да простят меня те, кого зовут Тимоти), так что для обозначения машинного интерфейса AS/400 мы будем использовать старую аббревиатуру «MI».
, представляет собой формальное определение интерфейса для всех приложений и большинства компонентов операционной системы. Аппаратура, а также все программное обеспечение операционной системы, которому должны быть доступны подробности аппаратной реализации, располагаются ниже границы MI.
Чтобы понять, как достигается независимость программного обеспечения от изменений в аппаратуре, обусловленных технологическим прогрессом, необходимо кратко рассмотреть, как работает компилятор. Ранее было сказано, что в традиционной процессоро-ориентированной системе компилятор генерирует двоичный машинный код непосредственно из исходного текста, что иногда требует дополнительного шага ассемблирования. В AS/400 компилятор генерирует из исходного текста код MI, который оформляется в виде так называемого шаблона программы. На втором этапе транслятор AS/400 генерирует двоичный код по содержимому шаблона программы. Фактически, этот транслятор выполняет те же действия, что и заключительный проход современного компилятора. Затем, если явно не запрошено его удаление, шаблон программы сохраняется вместе с двоичным кодом в программном объекте. Такая программа называется отслеживаемой (observable). При переносе программного объекта на новую аппаратную базу, например, на 64-разрядный PowerPC, другой транслятор, созданный для новой аппаратуры, перетранслирует шаблон программы в новый двоичный код. Изменений в исходном коде при этом не требуется — чем и достигается независимость от технологии. Более подробное рассмотрение этого вопроса мы отложим до главы 4.
Читать дальше