ОБЪЕКТНО-ОРИЕНТИРОВАННЫЙ ПОДХОД И СЕТЕВОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ

advertisement
ОБЪЕКТНО-ОРИЕНТИРОВАННЫЙ
ОБЕСПЕЧЕНИЕ
ПОДХОД
И
СЕТЕВОЕ
ПРОГРАММНОЕ
А.И.Илюшин, Н.Б.Дерябин, Журнал «ПРОГРАММИРОВАНИЕ» №6,1990
1.ВВЕДЕНИЕ
Использование объектно-ориентированнного подхода, как нам кажется, дает
существенные результаты практически во всех областях программирования. Не является
исключением и сетевое программное обеспечение. В ИПМ АН СССР накоплен довольно
большой опыт создания и использования сетей ЭВМ с объектно-ориентированной
архитектурой. В период с 1976 г. по 1981 г. были сделаны пробные реализации и построена
объектно -ориентированная сетевая архитектура, которая и используется по настоящее
время[1,2]. В 1983 г. была введена в эксплуатацию сеть СЕКОП из ЭВМ БЭСМ-6,
реализованная в соответствии с этой архитектурой. В 1988 г. была готова первая
реализация сети с объектно-ориентированной архитектурой для IBM PC, ДВК и ЕС ЭВМ.
Эта сеть получила название РУСЛАН и в настоящее время продолжает развиваться. Исходя
из нашего опыта, по-видимому, можно сделать два основных вывода:
- производительность программиста при создании распределенных программных
систем в сети с объектно-ориентированной архитектурой принципиально выше по
сравнению с работой в сети с традиционной архитектурой. Здесь под традиционной сетевой
архитектурой понимается представление распределенной программной системы в виде
совокупности распределенных по различным ЭВМ процессов. Причем эти процессы
взаимодействуют друг с другом, обмениваясь сообщениями с помощью примитивов
"послать - принять". Создавая распределенную систему, программист вынужден строить
частные протоколы связи между своими процессами, что является нетривиальной задачей
по крайней мере для программиста, привыкшего к традиционному локальному
программированию. В сети с объектно-ориентированной архитектурой распределенная
программная система строится в виде совокупности объектов-исполнителей операций,
распределенных по различным ЭВМ. Эти объекты взаимодействуют путем вызова операций друг в друге. В этом случае локальный и удаленный вызовы операций синтаксически
неразличимы в тексте программы. Сеть, как средство, связи превращается просто в один
частный случай механизма связи между вызывающей и вызываемой программами. Как
следствие сложность локального и распределенного программирования при прочих равных
условиях становится практически одинаковой;
- производительность во время счета и требования к ресурсам в сети с объектноориентированной архитектурой как минимум не хуже по сравнению с сетью, основанной на
"послать-принять".
Принципы построения сети с объектно-ориентированной архитектурой, разработанной
в ИПМ АН СССР, интерфейсы для пользователей, сетевой протокол удаленного вызова
операций описаны достаточно подробно в ранее опубликованных работах [1,2,3,4,5]. В
данной статье нам хотелось бы остановиться в основном на другой стороне проблемы обратном влиянии сетевой архитектуры на объектно-ориентированные средства. Дело в
том, что распространение некоторого метода за пределы области, в которой он
первоначально возник, часто приводит к полезному обобщению этого метода, очищению
его от частных решений, которые естественным, однако логически не обязательным,
образом были привнесены в него из исходной области применения. Как нам кажется, в
объектно-ориентированном подходе именно так обстоит дело с динамическим связыванием, ссылками на объекты, а также со способом создания, хранения и адресации объектов.
В сетевой обстановке перечисленные проблемы по необходимости должны решаться
способом, отличным от тех, которые используются в известных нам локальных реализациях
(см., например, [6]).
До рассмотрения именно различий локального и распределенного случаев нам
необходимо хотя бы кратко описать распределенный случай объектно-ориентированного
подхода. Некоторое количество локальных реализаций объектно-ориентированного
подхода считается известными.
2.ОБЪЕКТНО-ОРИЕНТИРОВАННАЯ СЕТЕВАЯ АРХИТЕКТУРА
Начнем с перечисления проблем, которые должны быть решены в рамках любой
архитектуры для распределенной обработки:
- адресация в пределах сети компонент распределенной
системы (программ и данных);
- связывание удаленных компонент в единую систему. В локальном случае в качестве
аналога такого механизма можно, например, указать загрузку подпрограммы из библиотеки
по имени в вызывающей программе;
- преобразование представления данных для разных ЭВМ,
ОС и языков;
- нейтрализация сбоев и отказов. С одной стороны, сбои и отказы гораздо более
вероятны в распределенном случае по сравнению с локальным, а с другой стороны,
благодаря доступности многих ЭВМ, возможно продолжение счета даже в случае отказа
отдельных узлов сети;
- параллелизм выполнения, который является реальным в отличие от имитируемого в
случае одной ЭВМ.
Рассмотрим объектно-ориентированную сетевую архитектуру, использованную при
разработке сети РУСЛАН. Прикладной уровень строится в виде множества объектовисполнителей операций, которые взаимодействуют путем вызова операций друг в друге.
Удаленный вызов операций поддерживается с помощью единственного протокола УДВ.
Этот протокол в данной архитектуре заменяет собой протоколы общего назначения на
прикладном уровне модели ISO/OSI [7], а также протоколы 6, 5 и 4 уровней этой модели.
Протоколы нижележащих уровней можно считать неспецифичными для моделей.
Потенциально бесконечное множество прикладных протоколов для частных применений
модели ISO/OSI заменяются просто конкретными прикладными подсистемами (объектамиисполнителями), взаимодействие которых, вообще говоря, не несет никакой сетевой
специфики. Для программирования распределенных сетевых систем естественно использовать широко распространенные языки, например такие, как Си и Фортран, расширив
их соответствующими средствами. При объектно-ориентированном расширении языков для
распределенной обработки были использованы следующие понятия:
- переменная типа объект-исполнитель операций. Под типом здесь понимается
набор имен операций, которые может выполнять объект, указываемый данной переменной.
Значением такой переменной является ссылка на объект-исполнитель, который расположен
возможно в удаленной ЭВМ. В данном изложении нам удобно называть переменными
также и формальные параметры процедур (подпрограмм);
- кластер, являющийся реализацией типа объекта-исполнителя. Кластер
представляет собой набор подпрограмм, реализующий операции данного типа. Для этого
набора подпрограмм в заголовке кластера определяются общие переменные, называемые
представлением объекта;
- экземпляр объекта-исполнителя или просто объект-исполнитель. Создается из
кластера и индивидуального набора значений переменных представления;
- файл объектов - это специальный объект, умеющий выполнять операцию "создать
объект" с указанным кластером, а также операции "уничтожить", "найти". Значением
переменной, заданной в качестве параметра-результата операции создания исполнителя,
становится ссылка на созданный объект. Естественно, что с одним кластером может быть
создано много объектов. Существенно, что одной переменной могут быть в разные
моменты присвоены ссылки на исполнители с разными кластерами, но, естественно, с
соответствующими наборами операций (в объектно-ориентированных языках такое
свойство называется полиморфизмом). Единственное условие - набор имен операций,
определяющий тип переменной, должен быть подмножеством набора имен операций,
реализуемых кластером созданного объекта. Файлы объектов могут располагаться как в
оперативной памяти, так и на дисках. Введение файлов объектов - это принципиальный
шаг, позволяющий в единой системе программирования естественным образом объединить
как традиционные языковые средства, так и некоторые возможности баз данных;
- вызов операции в объекте-исполнителе. Вызываемый объект задается переменной
типа исполнитель. В качестве параметров вызова могут передаваться как переменные
традиционных типов, так и переменные типа "объект-исполнитель операций"
(динамическое связывание в терминологии объектно-ориентированных языков).
В целом предлагаемая схема функционирования прикладного уровня такова:
- имеется множество объектов-исполнителей операций, которые хранятся в файлах
объектов. Файлы объектов возможно рассредоточены по различным ЭВМ сети;
- имеется множество процессов, выполняющих подпрограммы в кластерах объектов.
В момент вызова операции в другом объекте, возможно удаленном, процесс "перетекает" в
этот другой объект;
- сама совокупность взаимодействующих объектов определяется ссылками, которые
хранятся в этих объектах в переменных типа "объект-исполнитель". Получаются эти
ссылки как аргументы или результаты вызовов операций.
В данной модели объекты и процессы находятся в соотношении "много - много". А
именно, один процесс может проходить через много объектов, расположенных в разных
ЭВМ. Конкретно это означает наличие распределенного по этим ЭВМ стека для вложенных
вызовов подпрограмм из кластеров объектов. С другой стороны, несколько процессов
могут одновременно войти в один объект. При необходимости они могут синхронизоваться
на общих переменных представления этого объекта. Для этого достаточен любой известный
в локальном случае набор средств.
Отметим, что в модели ISO/OSI принято соотношение "один
- один". А именно, процесс фактически отождествляется с подсистемой (объектом).
Перечислим, как решаются приведенные выше сетевые проблемы, когда
распределенная система представляет собой множество исполнителей, взаимодействующих
путем вызова операций:
- адресация. Значением переменной типа исполнитель является ссылка, указывающая
на объект-исполнитель, расположенный в любой ЭВМ сети. В ссылке хранится уникальный
в пределах всей сети идентификатор объекта (УИД), перечень указателей на операции,
которые может выполнять данный объект, и указатель на сетевую процедуру связи. УИД
может быть дополнен различного рода физическими адресами, оптимизирующими доступ.
Тогда вызов удаленной операции через рассматриваемую ссылку и процедуру связи
попадает в сетевое обеспечение, которое транспортирует его до вызываемого объектаисполнителя и возвращает назад результаты выполнения операции;
- связывание объектов-исполнителей в единую систему осуществляется путем
передачи ссылок на них как параметров операций. В частности, ссылки могут запоминаться
в объектах каталогах и получаться как результаты операций поиска по имени в этих
каталогах. Для переменной типа исполнитель всегда хранится перечень имен операций,
определяющий, так сказать, формальный тип данной переменной. При занесении в
переменную ссылки происходит связывание этой переменной с в общем случае удаленным
конкретным объектом-исполнителем. Связывание переменной типа объект-исполнитель
при присваивании ей значения с конкретным объектом и следовательно с набором
подпрограмм, реализующих операции, перечисленные в типе, можно рассматривать как
естественное распространение на объектно-ориентированный и распределенный случаи
механизма "знакомств", хорошо известного по системам типа MULTICS;
- преобразование представления. В механизм расширения языка программирования
объектно-ориентированными средствами входит генерирование по описаниям переменных
дескрипторов, описывающих их тип (целый, вещественный, массив, запись, исполнитель и
т.д.). Тогда сетевое обеспечение, имея в момент траспортировки вызова тип данных, тип
языка и тип ЭВМ, легко преобразует представление;
- нейтрализация сбоев. Хранение объектов в файлах объектов (стабильная память),
уникальные идентификаторы объектов позволяют естественным образом использовать
известную в базах данных технику неделимых цепочек операций, контрольных точек и
рестартов. Оказалось очень полезной в распределенном случае обработка исключительных
ситуаций, аналогичная локальной обработке. Исключительная ситуация распространяется
по цепочке вложенных вызовов "вверх" до обработчика через все ЭВМ, по которым прошел
процесс выполнения этих вложенных вызовов;
- параллелизм. В приводимой схеме среда связи между ЭВМ оказывается прозрачной
для вызовов операций. Сетевое обеспечение с логической точки зрения является лишь
некоторой частной реализацией общего механизма вызова операций. Все содержательные
действия выполняются внутри исполнителей. Поэтому проблемы создания процессов и их
синхронизации сводятся к локальному случаю и могут быть решены с помощью хорошо известных локальных средств, например, семафоров, мониторов и т.д.
Сделаем выводы из выше сказанного:
- в локальном случае хорошо известные средства создания программных систем как
совокупности подпрограмм, вызывающих друг друга, достаточны и удобны. Введение
объектов-исполнителей является естественным обобщением (добавляется новый тип исполнитель для переменных и параметров операций) этих хорошо известных средств.
Хорошо известные средства управления процессами в локальном случае также достаточны;
- распределенный случай сводится к локальному с помощью удаленного вызова
операций. Сеть становится одним из частных механизмов связи между подпрограммами.
Для программиста, с точки зрения техники программирования, исчезает разница между
локальным и распределенным случаями. Он может пользоваться в обоих случаях едиными
средствами, исторически доказавшими свою достаточность и удобство.
3. ВЛИЯНИЕ СЕТЕВОЙ ОБСТАНОВКИ НА ОБЪЕКТНО-ОРИЕНТИРОВАННЫЙ
ПОДХОД
Рассмотрим основные особенности сетевого случая по сравнению с локальным, а
также влияние этих особенностей на объектно-ориентированную архитектуру. Как нам
кажется, одно из существенных отличий распределенных систем от локальных в настоящее
время в том, что при раскрутке распределенных систем часто главная программа
запускается позже ряда подсистем, с которыми эта главная программа должна динамически
связаться и использовать их. Конечно, и в локальном случае можно найти примеры такой
ситуации. Например, операционная система запускается до любой прикладной системы,
которая использует ее операции. Однако, операционная система является
предопределенным объектом с предопределенным набором операций, и увязка с ними
выполняется чаще всего статически. Напротив, в распределенном случае естественно, что в
машинах-серверах заранее запускаются разнообразные подсистемы, к которым
впоследствии динамически подключаются программы-заказчики. Причем на разных ЭВМ,
возможно, имеются функциональные дубли подсистем, поставляемых различными
поставщиками, и программа-заказчик может динамически выбрать ту или иную реализацию
нужной ей функции. Реализация указанной возможности требует от языка
программирования и его поддержки времени счета ряда средств, которые, как нам кажется,
отсутствуют в известных нам объектно-ориентированных локальных реализациях.
Рассмотрим требуемые средства в порядке, соответствующем естественной
последовательности работы в сети ЭВМ. Требуется:
- возможность создать подсистему-исполнитель в виде объекта, который может
существовать нужный период времени и который может быть найден и использован
независимыми программами-заказчиками. Отсюда, естественным образом, по аналогии с
файловыми системами и базами данных возникает понятие файла объектов, уникальный
идентификатор объекта, ссылка на объект, в которой хранится этот идентификатор,
уникальный в пределах сети, каталоги, в которых ссылки на объекты регистрируются под
различными именами. В известных нам локальных реализациях объекты создаются
традиционными способами: в статической памяти программы, в "автоматической" памяти
(стек) и в heap памяти. Стабильная файловая память для объектов отсутствует;
- возможность динамически связать программу-заказчик с найденным объектомисполнителем. Отсюда вытекает потребность иметь в качестве значения переменной типа
исполнитель достаточно сложную ссылку на объект. В этой ссылке должен храниться набор
имен операций, необходимых программе-заказчику, а после связывания с конкретным
объектом УИД этого объекта, указатели на процедуры, реализующие операции, и т.д. Здесь
важно подчеркнуть, что тип переменной-исполнителя при написании программы-заказчика
услуг определяется в виде набора требуемых ей операций возможно путем рассмотрения
уже имеющихся подсистем и их наборов операций. При этом выбирается некоторое
удобное для данной программы подмножество операций. Именно поэтому в
использованной нами архитектуре под типом объекта-исполнителя понимается просто
набор имен операций. Это позволяет динамически связать программу-заказчик с любой
подсистемой, которая в частности реализует и подмножество операций с этими именами. В
таких сравнительно старых языках как Ада и Модула-2 динамическое связывание просто
отсутствует. В новых объектно-ориентированных системах на основе языка С++ и в
TURBO PASCAL 5.5 фирмы BORLAND динамическое связывание, следуя языку
СИМУЛА-67, ограничено соотношением базовый тип в программе-заказчике и
производный тип в подсистеме-исполнителе. При этом базовый тип должен быть явно
указан в описании производного типа и тем самым должен быть определен до него. Выше
было показано, что тип в программе-заказчике часто определяется позже реализации используемого объекта. Главное в данной ситуации то, что механизм динамического
связывания программы-заказчика с объектом -исполнителем, как нам кажется, никакого
отношения к содержательному понятию "наследования" и "родительского" типа не имеет.
Подведем некоторые итоги. Введение понятия файла объектов, трактовка типа
переменной-исполнителя, особенности реализации ссылок на объекты явились следствием
сетевой специфики и отсутствия соответствующих средств в известных нам локальных
реализациях объектно-ориентированных систем. Как нам кажется, указанные средства не
являются специфичными именно для распределенного случая и являются естественным
обобщением, уместным и для локального случая. В качестве примера возможного
применения этих средств в локальном случае укажем на использование стабильной
файловой памяти объектов для организации контрольных точек и рестартов, а также для
хранения общедоступных подсистем в крупных ЭВМ.
4. ПРИМЕР РАСПРЕДЕЛЕННОГО ПРОГРАММИРОВАНИЯ
Приведем пример, который написан на языке СИР2, являющимся объектноориентированным расширением языка СИ. Рассматриваются две программы, возможно
расположенные на разных ЭВМ. Программа-исполнитель на той ЭВМ, на которой она
выполняется, создает объект-исполнитель с кластером ANYCLUST и затем регистрирует
этот объект под именем ANYOBJ в некотором сетевом каталоге, известным в сети под
именем PUBLICDIR. Этот каталог возможно расположен на другой ЭВМ. Программазаказчик, выполняющаяся возможно на третьей ЭВМ, находит в сети этот объект и
вызывает в нем операцию ANYOPER1. Приводимые ниже программы могут быть
выполнены с использованием либо трех, либо двух, либо одной ЭВМ. При этом как
исходные тексты программ, так и машинный код (только в случае однотипных ЭВМ) будут
идентичными для всех трех случаев.
/* ------------
программа-исполнитель
/* определение кластера ANYCLUST */
clust ANYOPER1, ANYOPER2 ANYCLUST
/* переменные представления объекта */
int ... ; char ... ; serv ... ; и т.п.
;
clbody ANYCLUST
oper ANYOPER1( ... )
---------------*/
/* тело функции, реализующей операцию ANYOPER1 */
oper ANYOPER2( ... )
/* тело функции, реализующей операцию ANYOPER2 */
/* Головная функция */
main()
/* описание четырех переменных типа объект-исполнитель, указывающих на:
- файл объектов текущей задачи - переменная TFO
- предопределенный каталог текущей ЭВМ - переменная DIROWN
- общесетевой каталог, зарегистрированный в текущей ЭВМ под именем PUBLICDIR,
- переменная DIR
- вновь создаваемый объект - переменная OBJ
*/
serv CREATE TFO;
serv FIND, ENTER DIR, DIROWN;
serv ANYOPER1, ANYOPER2 OBJ;
/* Сетевое инициирование */
ninit();
/* Получение ссылок на файл объектов задачи и каталог своей ЭВМ */
get_tfo(res TFO);
get_dir(res DIROWN);
/* Создание объекта */
TFO.CREATE(res OBJ, ANYCLUST);
/* Подключение к сетевому каталогу */
DIROWN.FIND(res DIR, "PUBLICDIR");
/* Регистрация объекта в каталоге */
DIR.ENTER(OBJ, "ANYOBJ");
/* Остаемся резидентом в ожидании вызовов операций */
nkeep();
/* ------------
программа-заказчик
---------------*/
main()
serv FIND DIR, DIROWN;
serv ANYOPER1 OBJ;
/* Сетевое инициирование */
ninit();
/* Получение ссылки на каталог своей ЭВМ */
get_dir(res DIROWN);
/* Подключение к сетевому каталогу */
DIROWN.FIND(res DIR, "PUBLICDIR");
/* Поиск объекта в каталоге */
DIR.FIND(res OBJ, "ANYOBJ");
/* Вызов целевой операции */
OBJ.ANYOPER1( ... );
ЛИТЕРАТУРА
1. А.И. Илюшин, и др. Вызов процедур в распределенных системах. Методические
материалы и документация по пакетам прикладных программ, вып. 24, ч. 1, Москва,
МЦНТИ, 1983, стр. 104-130.
2. A.I.Ilushin, A.N.Myamlin, V.S.Shtarkman, Computer Network Software Design Based
on Abstract Objects, Information Processing 83, Paris, 1983, pp. 23-28.
3. С.А.Васильев, и др. Объектно-ориентированные средства для программирования
распределенных систем. Методические материалы и документация по пакетам прикладных
программ, вып. 31, ч. 1, Москва, МЦНТИ, 1986, стр. 30-57.
4. Дерябин Н.Б., Илюшин А.И. Распределенное программирование на базе языка Си.
XIV Всесоюзная школа-семинар по вычислительным сетям. Тезисы докладов. МоскваМинск, 1989, ч.1, стр. 53-58.
5. Савицкая О.А., Илюшин А.И., Дерябин Н.Б. Распределенные вычисления в
Фортране. XIV Всесоюзная школа-семинар по выч. сетям. Тезисы докладов. МоскваМинск, 1989, ч.3, стр. 286-290.
6. Bjarne Stroustrup, The C++ Programming Language, Addison-Wesley, 1986, 328 pp.
7. ISO 7498 Information processing systems - Open Systems Interconnection - Basic
Reference Model.
Телефон для справок: 333-80-55 (Москва)
Download