Рейтинговые книги
Читем онлайн Параллельное и распределенное программирование на С++ - Хьюз Камерон

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 133 134 135 136 137 138 139 140 141 ... 181

Особый интерес для нашей «классной доски» представляют операции pvm_barrier() и pvm_joingroup(), поскольку существуют ситуации, в которых «классная доска» не запускает новые источники знаний до тех пор, пока определенная группа источников знаний не завершит свою работу. Для блокирования вызывающего процесса до нужного момента (до окончания обработки данных соответствующими источниками знаний) можно использовать операцию pvm_barrier (). Например, «классная доска» в качестве консультанта по выбору курсов обучения не будет активизировать источник знаний, отвечающий за составление расписания, до тех пор, пока не представят свои предложения источники знаний, которые специализируются на основных, общеобразовательных, второстепенных и факультативных курсах. Поэтому «классная доска» будет использовать операцию pvm_barrier () для ожидания завершения работы этой группы PVM-задач. На рис. 13.5 представлена UML-диаграмма видов деятельности, которая позволяет понять, как синхронизируются источники знаний и «классная доска».

Барьер синхронизации здесь реализуется с помощью операций pvm_barrier () и pvm_joingroup (). Реализация операторной функции для объекта задачи приве д ена в л истин г е 13.5.

Таблица 13.2. Групповые PVM-операции

int pvm_joingroup (char *groupname);Вносит вызывающий процесс в группу groupname, а затем возвращает int-значение, которое представляет собой номер процесса в этой группе

int pvm_lvgroup (char *groupname); Удаляет вызывающий процесс из группы groupname

int pvm_gsive (char *groupname); Возвращает int-значение, которое представляет собой количество членов в группе groupname

int pvm_gettid (char *groupname, int inum); Возвращает int-значение, равное идентификационному номеру задачи, выполняемой процессом, который идентифицируется именем группы groupname и номером экземпляра inum

int pvm_getinst (char *groupname, int taskid); Возвращает int-значение, которое представляет собой номер экземпляра, связанный с именем группы groupname и процессом, выполняющим задачу с идентификационным номером taskid

int pvm_barrier (char *groupname, int count); Блокирует вызывающий процесс до тех пор, пока count членов в группе groupname не вызовут эту функцию

int pvm_bcast (char *groupname, int messageid); Передает всем членам группы groupname сообщение, хранимое в активном буфере отправки, связанном с номером messageid

int pvm_reduce (void *operation, void *buffer, int count, int datatype, int messageid, char *groupname, int root); Выполняет глобальную операцию operation во всех процессах группы groupname

Рис.13.5. UML-диаграмма видов деятельности, отображающая синхронизацию «классной доски» и источников знаний

// Листинг 13.5. Определение функции operator() // в классе task

void task::operator()(string X) {

int cc; pvm_mytid();

cc = pvm_spawn(const_cast<char *>(X.data()),NULL,0,"",l, &Tid[N]);

N++;

}

Функция-оператор operator () используется для порождения PVM-задач. Имя задачи содержится в элементе X. data (). При обращении к функции pvm_spawn () (см. листинг 13.5) создается одна задача, а ее идентификационный номер сохраняется в элементе Tid[N] . (Подробнее о функции pvm_spawn () и вызове PVM-задач см. гла-вуб.) Класс task используется для создания функциональных объектов (объектов-функций). При выполнении алгоритма

for_each(Solve.begin(),Solve.end(),Task);

вызывается функция operator (), которая выполняет объект Task. Эта операция заставляет активизироваться источники знаний, содержа щ иеся в контейнере Solve. Алгоритм for_each () гарантирует активизацию всех источников знаний. Если используется м одель SIMD, то в алгоритме for_each () нет никакой необходимости. Вместо него прямо в конструкторе «классной доски» мы используем вызов функции pvm_spawn(). В листинге 13.6 как раз и показано, как при использовании модели SIMD можно запустить множество PVM-задач из конструктора «классной доски».

// Листинг 13.6. Запуск PVM-задач из конструктора

// класса task

void task::operator()(string X) {

int cc; pvm_mytid();

cc = pvm_spawn(const_cast<char *>(X.data()),NULL,0,"",l, &Tid[N]);N++;

}

Связь «классной доски» и источников знаний

Согласно коду, приведенному в листинге 13.6, порождается 20 источников знаний. Сначала все они выполняют одинаковый код. После их порождения «классная доска» должна отправить сообщения с указанием, какую роль они будут играть в процессе решения задачи. При использовании данной конфигурации источники знаний и «классная доска» являются частью PVM-среды. После создания источники знаний будут взаимодействовать с «классной доской» путем соединения с портом, на котором она размещается, или по ее адресу в сети intranet или Internet. Для этого источникам знаний понадобится объектная ссылка на «классную доску». Эти ссылки можно «зашить» в код источников знаний, или они могут прочитать их из файла конфигурации либо получить из службы имен. Имея ссылку, источник знаний взаимодействует с ORB-брокером (Object Request Broker — брокер объектных запросов), чтобы найти удаленный объект, содержащий реальные данные (знания) и активизировать его. Для нашего примера мы назначаем «классной доске» конкретный порт и запускаем CORBA-объект «классной доски» с помощью следующей ко м анды,

blackboard -ORBIIOPAddr inet:porthos:12458

По этой команде запускается наша программа «классной доски» с подключением к порту 12458 хоста porthos. Запуск CORBA-объекта зависит от используемой CORBA-реализации. В данном случае мы используем «открытую» CORBA-реализацию Mico [25] При выполнении программы blackboard реализуется экземпляр «классной доски», который в свою очередь порождает источники знаний. В созданных источниках знаний жестко закодирован номер порта, по которому они будут связываться с «классной доской». Фрагмент кода реализации источника знаний, который связывается с CORBA - ориентированным объектом «классной доски», представлен в листинге 13.7.

// Листинг 13.7. Код источника знаний, который связывается

// с CORBA-ориентированной «классной доской»

1 #include «pvm3.h»

2 using namespace std;

3 #include <iostream>

4 #include <fstream>

5 #include <string.h>

6 #include <strstream>

7 #include «black_board_impl.h» 8

9 int main(int argc, char *argv[])

10 {

11 CORBA::ORB_var Orb = CORBA::ORB_init(argc, argv,«mico-local-orb»);

12 CORBA::Object_yar Obj =Orb->bind(«IDL:black_board:1.0»,«inet:por thos:12 4 5 8»);

13 courses Courses;

14 //...

15 //...

16 black_board_var BlackBoard = black_board::_narrow(Obj);

17

18 int Pid;

19 //...

20 //... 21

22 cout « «Источник знаний создан.» « endl;

23 Courses.length(2);

24 Courses[0] = 255551;

25 Courses[l] = 253212;

26 string FileName;

27 strstream Buffer;

28 Pid = pvm_mytid();

29 Buffer « «Результат.» « Pid « ends;

30 Buffer » FileName;

31 ofstream Fout(FileName.data());

32 BlackBoard->suggestionsForMajor(Courses);

33 Fout.close();

34 pvm_exit();

35 return(0);

36 } 37

В строке 11 (см. листинг13.7) инициализируется ORB брокер . При выполнении строки 12 осу щ ествляется связывание имени объекта black_board с портом 12458 и возвра щ ается ссылка на CORBA-объект в переменной Obj. Строку 16 можно расценивать как разновидность операции приведения типа, чтобы Переменная BlackBoard ссылалась на объект «правильного размера». После того как источник знаний реализовал объект BlackBoard, он может вызывать любой метод, объявленный в интерфейсе black_board, код которого приведен в листинге 13.1. Обратите внимание на создание в строке 13 объекта Courses. Вспомните, что тип courses изначально был определен как CORBA-тип sequence. Здесь источник знаний использует класс courses, созданный во время IDL-компиляции. Добавление элементов в этот класс можно представить как добавление элементов в любой массив. При выполнении строк 24 и 25 в объект Courses добавляются два элемента, а в строке 32 содержится вызов метода, которому в качестве параметра передается объект Courses: BlackBoard->suggestionsForMaj or(Courses)

1 ... 133 134 135 136 137 138 139 140 141 ... 181
На этой странице вы можете бесплатно читать книгу Параллельное и распределенное программирование на С++ - Хьюз Камерон бесплатно.
Похожие на Параллельное и распределенное программирование на С++ - Хьюз Камерон книги

Оставить комментарий