- •Введение
- •Этапы большого пути
- •Библиотеки для параллельного и распределенного программирования
- •Новый единый стандарт спецификаций unix
- •Для кого написана эта книга
- •Среды разработки
- •Дополнительный материал Диаграммы uml
- •Профили программы
- •Параграфы
- •Тестирование кода и его надежность
- •Ждем ваших отзывов!
- •Благодарности
- •Преимущества параллельного программирования
- •Что такое параллелизм
- •Два основных подхода к достижению параллельности
- •Преимущества параллельного программирования
- •Простейшая модель параллельного программирования (pram)
- •Простейшая классификация схем параллелизма
- •Преимущества распределенного программирования
- •Простейшие модели распределенного программирования
- •Мультиагентные распределенные системы
- •Минимальные требования
- •Декомпозиция
- •Синхронизация
- •Базовые уровни программного параллелизма
- •Параллелизм на уровне инструкций
- •Параллелизм на уровне подпрограмм
- •Параллелизм на уровне объектов
- •Параллелизм на уровне приложений
- •Стандарт mpi
- •Pvm: стандарт для кластерного программирования
- •Стандарт corba
- •Реализации библиотек на основе стандартов
- •Среды для параллельного и распределенного программирования
- •Проблемы параллельного и распределенного программирования
- •Кардинальное изменение парадигмы
- •Проблемы координации
- •Проблема №3: взаимоблокировка
- •Проблема №4: трудности организации связи
- •Отказы оборудования и поведение по
- •Негативные последствия излишнего параллелизма и распределения
- •Выбор архитектуры
- •Различные методы тестирования и отладки
- •Связь между параллельным и распределенным проектами
- •Определение процесса
- •Два вида процессов
- •Блок управления процессами
- •Анатомия процесса
- •Состояния процессов
- •Планирование процессов
- •Стратегия планирования
- •Использование утилиты ps
- •Установка и получение приоритета процесса
- •Переключение контекста
- •Создание процесса
- •Отношения между родительскими и сыновними процессами
- •Утилита pstree
- •Использование системной функции fork()
- •Использование семейства системных функций exec
- •Функции execl ()
- •Функции execv ()
- •Определение ограничений для функций exec ()
- •Чтение и установка переменных среды
- •Использование posix-функций для порождения процессов
- •Идентификация родительских и сыновних процессов с помощью функций управления процессами
- •Завершение процесса
- •Ресурсы процессов
- •§ 3.1 • Граф распределения ресурсов ,
- •Типы ресурсов
- •Posix-функции для установки ограничений доступа к ресурсам
- •Асинхронные и синхронные процессы
- •Функция wait ()
- •Разбиение программы на задачи
- •Линии видимого контура
- •Определение потока
- •Контекстные требования потока
- •Сравнение потоков и процессов
- •Различия между потоками и процессами
- •Потоки, управляющие другими потоками
- •Преимущества использования потоков
- •Переключение контекста при низкой (ограниченной) доступности процессора
- •Возможности повышения производительности приложения
- •Простая схема взаимодействия между параллельно выполняющимися потоками
- •Упрощение структуры программы
- •Недостатки использования потоков
- •Потоки могут легко разрушить адресное пространство процесса
- •Один поток может ликвидировать целую программу
- •Потоки не могут многократно использоваться другими программами
- •Анатомия потока
- •Атрибуты потока
- •Планирование потоков
- •Состояния потоков
- •Планирование потоков и область конкуренции
- •Стратегия планирования и приоритет
- •Изменение приоритета потоков
- •Ресурсы потоков
- •Модели создания и функционирования потоков
- •Модель делегирования
- •Модель с равноправными узлами
- •Модель конвейера
- •Модель «изготовитель-потребитель»
- •Модели spmd и мрмd для потоков
- •Введение в библиотеку Pthread
- •Анатомия простой многопоточной программы
- •Компиляция и компоновка многопоточных программ
- •Создание потоков
- •Получение идентификатора потока
- •Присоединение потоков
- •Создание открепленных потоков
- •Использование объекта атрибутов
- •Создание открепленных потоков с помощью объекта атрибутов
- •Управление потоками
- •Завершение потоков
- •Точки аннулирования потоков
- •Очистка перед завершением
- •Управление стеком потока
- •Установка атрибутов планирования и свойств потоков
- •Установка области конкуренции потока
- •Использование функции sysconf ()
- •Управление критическими разделами
- •Безопасность использования потоков и библиотек
- •Разбиение программы на несколько потоков
- •Использование модели делегирования
- •Использование модели сети с равноправными узлами
- •Использование модели конвейера
- •Использование модели «изготовитель-потребитель»
- •Создание многопоточных объектов
- •Синхронизация параллельно выполняемых задач
- •Координация порядка выполнения потоков
- •Взаимоотношения между синхронизируемыми задачами
- •Отношения типа старт-старт (cc)
- •Отношения типа финиш-старт (фс)
- •Отношения типа старт-финиш (сф)
- •Отношения типа финиш-финиш (фф)
- •Синхронизация доступа к данным
- •Модель ррам
- •Параллельный и исключающий доступ к памяти
- •Что такое семафоры
- •Операции по управлению семафором
- •Мьютексные семафоры
- •Использование мьютексного атрибутного объекта
- •Использование мьютексных семафоров для управления критическими разделами
- •Блокировки для чтения и записи
- •Использование блокировок чтения-записи для реализации стратегии доступа
- •Условные переменные
- •Использование условных переменных для управления отношениями синхронизации
- •Объектно-ориентированный подход к синхронизации
- •Классические модели параллелизма, поддерживаемые системой pvm
- •Выполнение pvm-программы в виде двоичного файла
- •Запуск pvm-программ c помощью pvm-консоли
- •Запуск pvm-программ c помощью xpvm
- •Требования к pvm-программам
- •Методы использования pvm-задач
- •§ 6.1. Обозначение сочетаний
- •6.3. Базовые меха н измы pvm 233
- •Базовые механизмы pvm
- •Функции управления процессами
- •6.3. Базовые меха н измы pvm 235
- •Упаковка и отправка сообщений
- •6.3. Базовые механизмы pvm 237
- •Доступ к стандартному входному потоку (stdin) и стандартному выходному потоку (stdout) со стороны pvm-задач
- •Получение доступа к стандартному выходному потоку (cout) из сыновней задачи
- •Обработка ошибок, исключительных ситуаций и надежность программного обеспечения
- •Надежность программного обеспечения
- •Отказы в программных и аппаратных компонентах
- •Определение дефектов в зависимости от спецификаций по
- •Обработка ошибок или обработка исключительных ситуаций?
- •Надежность по: простой план
- •План а: модель возобновления, план б: модель завершения
- •Использование объектов отображения для обработки ошибок
- •Классы исключений
- •Классы runtime__error
- •Классы logic_error
- •Выведение новых классов исключений
- •Защита классов исключений от исключительныхситуаций
- •Диаграммы событий, логические выражения и логические схемы
- •Распределенное объектно-ориентированное программирование
- •Декомпозиция задачи и инкапсуляция ее решения
- •Взаимодействие между распределенными объектами
- •Синхронизация взаимодействия локальных и удаленных объектов
- •Обработка ошибок и исключений в распределенной среде
- •Доступ к объектам из других адресных пространств
- •Брокеры объектных запросов (orb)
- •Язык описания интерфейсов (idl):более «пристальный» взгляд на corba-объекты
- •Анатомия базовой corba-программы потребителя
- •Анатомия базовой corba-программы изготовителя
- •Базовый npoeкт corba-приложения
- •Получение ior-ссылки для удаленных объектов
- •Служба имен
- •§ 8.1. Семантические сети
- •Использование службы имен и создание именных контекстов
- •Служба имен «потребитель-клиент»
- •Подробнее об объектных адаптерах
- •Хранилища реализаций и интерфейсов
- •Простые pacnpeделенные Web-службы, использующие corba-спецификацию
- •Маклерская служба
- •Парадигма «клиент-сервер»
- •Реализация моделей spmd и mpmd с помощью шаблонов и mpi-программирования
- •Декомпозиция работ для mpi-интерфейса
- •Дифференциация задач по рангу
- •Группирование задач по коммуникаторам
- •Анатомия mpi-задачи
- •Использование шаблонных функций для представления mpi-задач
- •Реализация шаблонов и модельБрмо (типы данных)
- •Использование полиморфизмадля реализации mpmd-модели
- •Введение mpmd-модели c помощью функций -объектов
- •Как упростить взаимодействие между mpi-задачами
- •Визуализация проектов параллельных и распределенных систем
- •Визуализация структур
- •Классы и объекты
- •Отображение информации об атрибутах и операциях класса
- •Организация атрибутов и операций
- •Шаблонные классы
- •Отношения между классами и объектами
- •Интерфейсные классы
- •Организация интерактивных объектов
- •Отображение параллельного поведения
- •Сотрудничество объектов
- •Процессы и потоки
- •Отображение нескольких потоков выполнения и взаимодействия между ними
- •Последовательность передачи сообщений между объектами
- •Деятельность объектов
- •Конечные автоматы
- •Параллельные подсостояния
- •Распределенные объекты
- •Визуализация всей системы
- •Визуализация развертывания систем
- •Архитектура системы
- •Проектирование компонентов для поддержки параллелизма
- •Как воспользоваться преимуществами интерфейсных классов
- •Подробнее об объектно-ориентированном взаимном исключении и интерфейсных классах
- •«Полуширокие» интерфейсы
- •Поддержка потокового представления
- •Перегрузка операторов "«" и "»" для pvm-потоков данных
- •Пользовательские классы, создаваемые для обработки pvm-потоков данных
- •Объектно-ориентированные каналы и fifo-очереди как базовые элементы низкого уровня
- •Связь каналов c iostream-объектами с помощью дескрипторов файлов
- •18 Cerr « «Ошибка при создании канала " « endl;
- •Доступ к анонимным каналам c использованием итератора ostream_iterator
- •Fifo-очереди (именованные каналы),
- •Интерфейсные fifo-классы
- •Каркасные классы
- •Реализация агентно-ориентированных архитектур
- •Что такое агенты
- •Агенты: исходное определение
- •Типы агентов
- •В чем состоит разница между объектами и агентами
- •Понятие об агентно-ориентированном программировании
- •§ 12:1 Дедукция, индукция и абдукция
- •Роль агентов в распределенном программировании
- •Агенты и параллельное программирование
- •Базовые компоненты агентов
- •Когнитивные структуры данных
- •Методы рассуждений
- •Типы данных предположений и структуры убеждений
- •Класс агента
- •Цикл активизации агента
- •Простая автономность
- •12.6. Резюме
- •Реализация технологии «классной доски» с использованием pvm-средств, потоков и компонентов
- •Модель «классной доски»
- •Методы структурирования «классной доски»
- •Анатомия источника знаний
- •Стратегии управления для «классной доски»
- •Реализация модели «классной доски» с помощью corba-объектов
- •Пример использования corba-объекта «классной доски»
- •Реализация интерфейсного класса black_board
- •Порождение источников знаний в конструкторе «классной доски»
- •Порождение источников знаний с помощью pvm-задач
- •Связь «классной доски» и источников знаний
- •Активизация источников знаний с помощью posix-функции spawn()
- •Реализация модели «классной доски» с помощью глобальных объектов
- •Активизация источников знаний с помощью потоков
- •Приложение a
- •Диаграммы классов и объектов
- •Диаграммы сотрудничества
- •Диаграммы последовательностей
- •A.2.3. Диаграммы видов деятельности
- •A.3. Диаграммы состояний
- •A.4. Диаграммы пакетов
- •Приложение б 26
Брокеры объектных запросов (orb)
ORB-брокер действует от имени программы. Он посылает сообщения удаленному объекту и возвращает сообщения от него. Поведение ORB-брокера можно сравнить с посредником между локальными и удаленными объектами. ORB-брокер решает все вопросы, связанные с маршрутизацией запроса от программы к удаленному объекту и с маршрутизацией ответа программе, принятого от удаленного объекта. Такое посредничество делает коммуникации между системами практически прозрачными. ORB-брокер избавляет программиста от необходимости программирования сокетов между процессами, выполняющимися на различных компьютерах. И точно так же он устраняет необходимость в программировании каналов и очередей с FIFO-дисциплиной между процессами, выполняющимися на одном компьютере. Он берет на себя немалый объем сетевого программирования, без которого не обойтись при создании распределенных программ. Более того, он стирает различия между операционными системами, языками программирования и аппаратными средствами. При программировании локальных объектов программисту больше не нужно беспокоиться о том, на каком языке реализованы удаленные объекты, на какой платформе они выполняются и к какой сети они «приписаны»: Internet или локальной intranet. ORB-брокер использует IOR-ссылки, чтобы упростить взаимодействие между компьютерами, сетями и объектами. Обратите внимание на то, что IOR-ссылка (см. рис. 8.2) содержит информацию, которая может быть использована для TCP/IP-соединений. Мы представили лишь частичное описание IOR-компонентов, поскольку IOR-дескриптор должен быть «черным ящиком» для разработчика. ORB-брокер использует IOR-ссылки, чтобы найти объект назначения. Обнаружив объект, ORB-брокер активизирует его и передает аргументы, необходимые для вызова этого объекта. ORB-брокер ожидает завершения обслуживания запроса и возвращает вызывающему объекгу ожидаемую информацию или исключение, если вызов метода оказался неудачным. Упрощенная последовательность действий, выполняемых ORB-брокером от имени локального объекта, показана на рис. 8.3.
Действия, перечисленные на рис. 8.3, представляютупро щ енную схему того, что делает ORB-брокер, взаимодействуя с удаленным объектом. Эти действия практически незаметны для локального объекта. Локальный объект вызывает один из методов удаленного объекта, а ORB-брокер делает «свою работу» от имени локального объекта. ORB-брокер выполняет большой объем обработки, заключенный всего лишь в нескольких строках кода. Обычно распределенное объектно-ориенти-рованное приложение состоит по крайней мере из двух программ. Каждая программа имеет один или несколько объектов, которые взаимодействуют друг с другом, «пересекая» адресные пространства. Характер взаимодействия объектов определяется отношениями «клиент-сервер», «изготовитель-потребитель» или базируется на принципе равноправия (модель равноправных узлов). Следовательно, если у нас есть две программы, то одна будет действовать как клиент, а другая — как сервер, или одна — как изготовитель, а другая — как потребитель, либо обе они будут равноправными. В программе 8.1 реализован потребитель, который вызывает простой удаленный объект калькулятора. На примере этой программы демонстрируется, как можно получить доступ к удаленному объекгу, а также как инициализируется и используется ORB-брокер.
УПРОЩЕННАЯ ПОСЛЕДОВАТЕЛЬНОСТЬ ДЕЙСТВИЙ ORB-БРОКЕРА ПРИ ВЫЗОВЕ МЕТОДА УДАЛЕННОГО ОБЪЕКТА _
1. Найти удаленный объект. _
2. Активизировать модуль, содержа щ ий искомый объект, если таковой е щ е не активизирован. _
3. Передать аргументы удаленному объекту. _
4. Ожидать ответа после вызова метода удаленного объекта. _
5. Вернугьлокальномуобъекту информацию или исключение, если вызовудаленного метода оказался неуспешным. _
Рис. 8.3. Упрощенная последовательность действий, выполняемых ORB-брокером от имени локального объекта
// Программа 8.1
1 using namespace std;
2 #include «adding_machine_impl.h»
3 #include <iostream>
4 #include <fstream>
5 #include <string> 6
7
8 int main(int argc, char *argv[])
9 {
10 CORBA::ORB_var Orb = CORBA::ORB_init(argc, argv, «mico-local-orb»);
11 CORBA::BOA_var Boa = Orb->BOA_init(argc,argv,«mico-local-boa»);
12 ifstream In(«adding_machine.objid»);
13 string Ref;
14 if('In.eof()){
15 In » Ref;
16 }
17 In.close();
18 CORBA::Object_var Obj = Orb->string_to_object(Ref.data());
19 adding_machine_var Machine =adding_machine::_narrow(Obj);
20 Machine->add(700);
21 Machine->subtract(250);
22 cout << «Результат равен " « Machine->result()« endl;
23 return(0);
24 }
25
26
При выполнении строки 10 ORB-брокер инициализируетс я. Строка 15 обеспечивает считывание из файла IOR-ссылки на объект adding_machine. Одно из прекрасных свойств IOR-ссылки состоит в том, что ее можно хранить как простую строку и передавать другим программам. Передачу IOR-ссылки проще всего реализовать с помощью аргументов командной строки, переменных среды или файлов. IOR-ссылку можно отправить по электронной почте или с помощью протокола передачи файлов (File Transfer Protocol — FTP). IOR-ссылки совместно используют файловые системы, и их можно загружать с Web-страниц. Если некоторая программа имеет IOR-ссылку на удаленный объект, то для доступа к нему можно использовать ORB-брокер. Другие методы связи между объектами с помощью IOR-ссылок будут рассмотрены ниже в этой главе. Но для начала вполне достаточно использования файловых систем. Итак, в программе 8.1 IOR-ссылка была получена путем преобразования объектной ссылки в «строковую» форму (с использованием ORB-брокера удаленного калькулятора) и записана в файл. При выполнении строки 18 локальный объект Orb преобразует «строковую» IOR-ссылку обратно в объектную. В строке 19 эта объектнал ссылка используется для реализации объекта adding_machine. Обратите внимание на то, что при вызове методов этого объекта adding_machine выполняется соответствующий код удаленного калькулятора (см. строки 20, 21 и 22).
Machine->add(700) ;
Machine->subtract(250) ;
cout « «Результат равен " « Machine->result() « endl;
И хотя вызовы этих методов сделаны в нашей локальной области види м ости, они относятся к выполняемому колу в другом адресном пространстве (в данном случае — даже к другому компьютеру). Для разработчика местоположение объекта Machine как будто перестает иметь значение. После создания (в строке 19) этот объект используется как любой другой объект С++. И хотя существуют весьма значительные различия между вызовами локальных и удаленных объектов 15, объектно-ориентированное представление, тем не менее, поддерживается, и с точки зрения объектно-ориентированного программирования удаленные объекты ведут себя как локальные. Код, представленный в программе 8.1, является кодом клиентской части приложения (или кодом «потребителя»), поскольку в нем используются возможности объекта adding_machine. Поэтому теперь (для получения завершенного приложения калькулятора) нам нужен код «ответной части», который реализует объект adding_machine. Код этого второго компонента представлен в программе 8.2.
// Программа 8.2
1 #include <iostream>
2 #include <fstream>
3 #include «adding_machine_impl.h» 4
5 6 7
8 int main(int argc, char *argv[])
9 {
10 CORBA::ORB_var Orb = CORBA: :ORB_init(argc,argv,«mico-local-orb»);
11 CORBA::BOA_var Boa = Orb->BOA_init(argc,argv,«mico-local-boa») ;
12 adding_machine_impl *AddingMachine =new adding_machine_impl;
13 CORBA::String_var Ref = Orb->object_to_string(AddingMachine);
14 ofstream Out(«adding_machine.objid»);
15 Out « Ref « endl;
16 Out.close() ;
17 Boa->impl_is_ready (CORBA: : ImplementationDef : :_nil () ) ;
18 Orb->run();
19 CORBA: :release(AddingMachine) ;
20 return(0);
21 } 22 23
Обратите внимание на то, что программа-«изготовитель» также должна инициализировать объект Orb (в строке 10). Это — одно из важных требований, предъявляемых к CORBA-ориентированным программам, поскольку каждая программа реализует взаимодействие с удаленными объектами с помощью ORB-брoкepa. Именно поэтому инициализация ORB-объекта— первое действие, которое должна выполнить CORBA-программа. В строке 12 объявляется реальный объект adding_machine . Это именно тот объект, с которым в действительности связывается программа 8.1. В строке 13 объектная ссылка на реальный объект adding_machine преобразуется в «строковую» форму, а затем записывается в обычный текстовый файл, чтобы ее можно было без труда прочитать. После того как IOR-ссылка записана в файл, объект Orb ожидает запроса. При каждом вызове одного из его методов этот объект выполняет соответствующее арифметическое действие (сложение или вычитание). Значение результата передается посредством вызова метода result() объекта adding_machine. Программы 8.1 и 8.2 демонстрируют базовую структуру, которую должны иметь CORBA-программы. Код, создающий объект adding_machine, начинается с объявления его CORBA-класса. Каждый CORBA-объект начинается как IDL-проект (Interface Definition Language — язык описания интерфейсов).