Литмир - Электронная Библиотека

Рис.8.1. Логическая структура и распределение объектов в моделях «изготовитель-потребитель», равноправных узлов, «классной доски» и мультиагентной системы

Если объекты относятся к одному и тому же процессу, то в качестве средств межобъектно г о «общения» можно использовать механизм передачи параметров, вызовы обычных методов и использование г лобальных переменных. Если объекты принадлежат различным процессам, выполняемым на одном компьютере, то средствами ком м уникации между объекта м и м огут служить файлы, каналы, очереди c дисциплиной обслуживания «первы м пришел — первы м обслужен», разделяе м ал па м ять, буферы об м ена или пере м енные среды. Если же объекты «прописаны» на различных компьютерах, то в качестве средств связи придется использовать сокеты, вызовы удаленных процелур и дру г ие типы средств сетево г о про г раммирования. При это м мы должны поду м ать не только о то м, как булут общаться объекты в распределенном приложении, но и о том, посредство м че г о будет реализовано это об щ ение. Объектно- ориентированные приложения могут включать как простые типы данных, так и довольно сложные, а именно классы, определенные пользователем. Такие классы часто используются для связи между объектами. Поэтому связь между распределенными объектами будет обеспечиваться не только с помощью простых встроенных типов данных (например int, float или double), но и посредством классовых типов, определенных пользователем, без которых некоторые объекты не смогут выполнить свою работу. Кроме того, необходимо позаботиться о том, чтобы у одних объектов была возможность вызывать методы других объектов, расположенных в других адресных пространствах. Более того, необходимо прелусмотреть возможность для одного объекта «знать» о методах удаленных объектов. В то время как язык С++ поддерживает средства объектно-ориентированного программирования, в нем не предусмотрено никаких встроенных средств по обеспечению связи между распределенными объектами. Он не содержит никаких встроенных методов для локализации удаленных объектов и формирования к ним запросов.

Для реализации связи между распределенными объектами разработан ряд протоколов. Двумя наиболее важными из них являются IIOP (Internet Inter-ORB Protocol — протокол, определяющий передачу сообщений между сетевыми объектами по TCP/IP) и RMI (Remote Method Invocation — вызов удаленных методов). С помощью этих протоколов могут общаться объекты, расположенные практически в любом мести сети. В этой главе мы рассмотрим методы реализации распределенных объектно-ориентированных программ с использованием упомянутых протоколов и спецификации CORBA (Common Object Request BrokerArchitecture). Спецификация CORBA представляет собой промышленный стандарт для определения отношений, взаимодействий и связей между распределенными объектами. IIOP и GIOP — два основных протокола, с которыми работает спецификация CORBA. Эти протоколы хорошо согласуются с протоколом TCP/IP. CORBA — самый простой и наиболее гибкий способ добавления средств распределенного программирования в среду С++. Средства, предоставляемые спецификацией CORBA, реализуют поддержку двух основных моделей объектно-ориентированного параллелизма, которые мы используем в этой книге: «классная доска» и мультиагентные системы. Поскольку спецификация CORBA отражает принципы объектно-ориентированного программирования, с ее помощью можно реализовать приложения довольного широкого диапазона: от миниатюрных до очень больших. В этой книге мы используем MICO [14] — открытую реализацию спецификации CORBA. MICO-реализация поддерживает основные CORBA-компоненты и службы. С++ взаимодействует с MICO посредством коллекции классов и библиотек классов. Спецификация CORBA поддерживает распределенное объектно-ориентированное моделирование на каждом его уровне.

Синхронизация взаимодействия локальных и удаленных объектов

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

Обработка ошибок и исключений в распределенной среде

Возможно, одной из самых сложных областей обработки исключительных ситуаций или ошибок в распределенной среде считается область частичных отказов. В распределенной системе могут отказать один или несколько компонентов, в то время как другие компоненты будут функционировать в «предположении», что в системе все в полном порядке. Если такая ситуация (например, отказ одной функции) возникает в локальном приложении, т.е. когда все компоненты принадлежат одному и тому же процессу, об этом нетрудно уведомить все приложение в целом. Но для распределенных приложений все обстоит иначе. На одном компьютере может отказать сетевая карта, а объекты, выполняемые на других компьютерах, могут вообще не «узнать» о том, что где-то в системе произошел отказ. Что случится, если один из объектов попытается связаться с другим объектом и вдруг окажется, что сетевые связи с ним оборвались? Если при использовании модели равноправных узлов (в которой мы формируем различные группы объектов по принципу решения различных аспектов проблемы) одна из групп откажет, то как об этом отказе «узнают» другие группы? Более того, какое поведение мы должны «навязать» системе в такой сигуации? Должен ли отказ одного компонента приводить к отказу всей системы? Если даст сбой один клиент, то должны ли мы прекратить работу сервера? А если откажет сервер, то нужно ли останавливать клиент? А что, если сервер или клиенты продемонстрируют лишь частичные отказы? Поэтому в распределенной системе, помимо «гонок» данных и взаимоблокировок, мы должны также найти способы справляться с частичными отказами компонентов. И снова-таки подчеркиваем, важно найти распределенный подход к С++-механизму обработки исключительных сигуаций. Для начала нас удовлетво-рятвозможности, предоставляемые спецификацией CORBA.

Доступ к объектам из других адресных пространств

Объекты, разделяющие одну область действия (видимости), могут взаимодействовать, получал доступ друг к другу по именам, псевдонимам или с помощью указателей. Объект доступен только в случае, если «видимо» его имя или указатель на него. Видимость имен объектов определяется областью действия. С++ рааличает четыре основ-ныхуровня областей действия:

• блока;

• функции;

• файла;

• класса.

Вспомните, что блок в С++ определяется фигурными скобками {}, поэтому присваивание значения Y переменной X в листинге 8.1 недопустимо, так как переменная Y видима только внутри блока. Функции main() неизвестно имя переменной Y за пределами блока, конец которого обозначен закрывающейся фигурной скобкой.

// Листинг 8.1. Простой пример области действия блока

int main(int argc, char argv[]) {

int X; int Z; {

int Y;

Z = Y; // Вполне правомочное присваивание.

//.. .

78
{"b":"233145","o":1}