ОС

В процессе модернизации операционных систем особенно актуальной становится проблема развития архитектуры ОС и общесистемных API при сохранении совместимости со старыми разработками. Один из вариантов решения этой проблемы мы все хорошо знаем: Microsoft при переходе на Windows 2003 настолько сильно изменила архитектуру, что для запуска старых приложений в новой среде порой возникает необходимость в продуктах-эмуляторах Virtual PC.

В 2000 г. Apple начала переход на операционную систему нового поколения Mac OS X, отличающуюся от предыдущей, Mac OS 9, куда больше, чем Windows 2003 Server отличается от Windows 3.1. В процессе этого перехода компании удалось адаптировать множество прогрессивных технологий и подходов и при этом сохранить высокую степень совместимости с прежними версиями ОС, а также заметно облегчить перенос старых приложений на новую ОС. В результате сегодня под Mac OS X создано заново или адаптировано более 10 000 программ, и еще примерно столько же унаследованных приложений работает под Mac OS X безо всяких изменений. Подход, использованный Apple при переходе на Mac OS X, в корне отличается от подхода Microsoft.

Общая структура Mac OS X

В Mac OS X принято выделять четыре функциональных слоя.

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

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

Общая структура системы Mac OS X

Третий слой включает программные интерфейсы приложений (API) различного происхождения и типа, основные из них - Classic, Carbon и Cocoa. Подсистема Classic, как это следует из названия, обеспечивает выполнение традиционных Маковских приложений. Carbon является неким "средством переходного периода" и позволяет создавать программы, одинаково хорошо работающие как на "классической" Mac OS, так и на "десятке". Подсистема Cocoa - полностью объектно-ориентированный набор сервисов и API. Обычно считается, что Carbon и Cocoa - "родные" API "десятки", поскольку оба могут использовать все преимущества этой системы, однако с точки зрения создания новых программ набор интерфейсов Cocoa является более предпочтительным.

Наконец, венчает весь этот стек слоев графический интерфейс пользователя Aqua.

Ядро Mac OS X Darwin

Более пристальное изучение Darwin позволяет выделить в его составе две подсистемы.

В основе новейшей версии Darwin 7.3 лежит микроядро Mach 3.0, поверх которого выполняются базовые сервисы BSD 5.0 (благодаря чему в подавляющем большинстве случаев можно воспринимать "десятку" просто как некий диалект UNIX).

Заметим, что оба компонента Darwin’а (и Mach, и значительная часть BSD) не принадлежат Apple. Они представляют собой независимые открытые проекты, и поэтому Darwin как целое также распространяется свободно в соответствии с открытой лицензией (она носит название Apple Public Source License и несколько отличается от более привычных лицензий GPI Free Software Foundation, BSD или Apache, хотя сертифицирована как Free Software Licenses организациями Open Source Initiative и Free Software Foundation). Выбор идеологии свободно распространяемого ПО в качестве базовой для построения "десятки" позволяет привлечь к разработке Mac OS X и поклонников BSD, и последователей Mach.

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

Следует отметить одну важную особенность Mach - полноценную поддержку многопроцессорности. Нужно сказать, что Mach полностью поддерживал многопроцессорность уже в самой первой версии; более того, способность работы на многопроцессорных и даже многокомпьютерных системах (типа современного Beowulf на базе Linux) была одной из основных движущих идей проекта Mach. Однако Mach - всего лишь набор достаточно примитивных базовых средств. Поэтому любая система на базе микроядра Mach всегда "окружается" еще одним слоем, реализующим зависимые от данной ОС высокоуровневые сервисы и представляющим собой собственно ОС в "бытовом" понимании этого слова. Однако именно "окружающий" слой до последнего времени создавал проблемы с многопроцессорностью.

В "десятке" ситуация кардинально изменилась - симметричная многопроцессорность (SMP) поддерживается повсеместно, начиная со встроенного в систему браузера файлов и всех сервисов системы. Ярким примером служит подсистема QuickTime - даже при воспроизведении на двухпроцессорном Power Mac одного ролика оба процессора загружаются одинаково.

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

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

"Десятка" предлагает возможности по работе с процессами и потоками на любой вкус. Самым нижним уровнем "процессов" являются, естественно, потоки самого микроядра Mach. Еще один фундаментальный тип процессов Mac OS X - процессы и потоки в стиле стандартов POSIX, используемые большинством UNIX-систем. Именно к операциям с потоками Mach либо с процессами и потоками POSIX преобразуется в конечном счете любая работа с потоками и процессами. Реализованы и другие UNIX-варианты потоков.

В случае API Classic (т. е. при выполнении "классических" Маковских программ) единственный способ задействования многопроцессорности связан с использованием довольно примитивного Classic MP API, появившегося еще в начале 1990-х. На "десятке" эти вызовы корректно преобразуются, что и позволяет даже старым приложениям задействовать несколько процессоров.

API Carbon предоставляет программисту средства API Thread Manager и Multiprocessing Services. Thread Manager - относительно примитивный API, позволяющий достаточно легко перенести приложение, работающее с потоками, из среды Classic в среду Carbon, однако не позволяющий использовать всех преимуществ многопроцессорности. А вот Multiprocessing Services дает возможность строить полноценные многопотоковые приложения - правда, ценой довольно сильного изменения "классического" кода.

При создании новых приложений на базе Cocoa можно использовать API NSThread и java.lang.Thread.

Особенности файловых систем

В отличие от подавляющего большинства других файловых систем, Маковская HFS (в том числе и ее расширенная версия HFS+ в Mac OS X) представляет всякий файл в виде двух совершенно различных "сущностей", называемых "Fork". Одна из них, Data Fork, хранит неструктурированные данные любого типа и сильно напоминает обычный файл Windows или UNIX. Другая, Resource Fork, имеет четко описанную структуру и содержит ресурсы программ или документов; в частности, именно здесь хранятся описания диалогов, меню, пиктограмм и т. д.

Предложенная в Mac OS структура файла оказалась очень удобной, но общий поток развития компьютерного мира выбрал себе другое русло, и эта идея была забыта... В качестве наследия остались постоянные вопросы новичков о том, почему при копировании с Мака на Windows одного файла появляется два...

Mac OS X может с равным успехом использовать не только файловую систему HFS, но и UFS, не имеющую никакого представления о специфике HFS, благодаря принятому при создании этой системы радикальному решению.

Mac OS X на уровне файловой системы работает (причем прозрачно) с новым типом хранения данных, называемым пакетами (Package), или, иногда, бандлами (Bundle). Для внешнего мира такой пакет представляет собой просто файл, который можно копировать с диска на диск и с компьютера на компьютер, причем свойства пакета при этом полностью сохраняются. Скажем, "файл", представляющий собой программу (разумеется, на самом деле это - пакет), после копирования по-прежнему можно запустить на исполнение. Таким образом, налицо сохранение всех преимуществ единственного файла.

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

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

Пакеты различного типа применяются в Mac OS X повсеместно; кроме программ пакетами являются и расширения ядра (Kernel Extensions), и специфические библиотеки функций, и даже файлы прикладных программ (скажем, презентация программы Keynote представляет собой пакет, в котором размещены файл текста презентации, файлы стандартных форматов для всех использованных рисунков или видеофрагментов, примененных шрифтов и т. д.).

Идея пакетов Mac OS X чрезвычайно плодотворна, поскольку позволяет реализовывать сколь угодно сложную логику хранения данных поверх абсолютно любой файловой системы и полную независимость от файловой системы.

Далее теоретически никто не мешает разработчику сделать пакет, содержащий коды для различных ОС, вариантов динамически подключаемых библиотек, дополнительного оборудования и даже различных В качестве еще одного преимущества можно назвать упрощение локализации программ. При локализации возникает необходимость перевода всех текстовых ресурсов, диалоговых окон, кнопок, меню и т. д., более того, хорошо локализованная программа подразумевает замену некоторых пиктограмм (например, пиктограммы почтового ящика, который выглядит по-разному в России, США и Германии). В "десятке" все локализованные ресурсы программы (или подсистемы ОС) находятся в едином "дереве локализации" пакета, но в различных его "поддеревьях", благодаря чему процедура локализации очень облегчается. Кстати, это означает, что "русских", "немецких" или "американских" "десяток" быть не может - они все всегда интернациональные. Более того, в "десятке" каждый пользователь не просто выбирает язык системы, а формирует целый список понятных ему языков, и при запуске любой программы система сначала пытается подключить ресурсы программы, относящиеся к самому верхнему языку в списке, при их отсутствии - ко второму и т. д. Этот список, кстати, можно менять динамически, даже в рамках одного сеанса работы пользователя. Похожие механизмы локализации встречаются и в других ОС, но только в Mac OS X они действительно прижились и стали общепринятыми.

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

В следующей части статьи мы опишем основные API системы Mac OS X.    

Окончпние следует