Параллельное программирование: Учебное пособие, страница 60

3.5.1  Дистанционные управления

В CC++ глобальные указатели используются таким же образом, как и локальные указатели в C++. Отличие состоит в том, что их используют для работы с данными или вызова функций, расположенных в других процессорных объектах. Рассмотрим следующий фрагмент кода:

global int *gp;      // Объявляются: глобальная переменная gp для пере-

int len2;                     // дачи данных и len2 – для результата вычислений.

           . . .

*gp = 5;                       // 5 будет передана в другой процессорный объект.

           . . .

len2 = (*gp)*2;      // Содержимое читается в вычисляемое выражение.

На рисунке 3.2 представлена временная диаграмма взаимодействия двух процессорных объектов, соответствующая приведенному фрагменту. Объявленный в процессорном объекте pobj1 глобальный указатель *gp, благодаря ссылке на него (*gp->length), вызывает в процессорном объекте pobj2 команду присваивания ссылочной переменной length значения равного 5. Использование в процессорном объекте pobj1 вычисляемого выражения, в котором в качестве операнда участвует содержимое глобального указателя, инициирует команду чтения значения ссылочной переменной. Пунктиром на временных развертках процессов выделены участки, где процесс обработки в процессорном объекте находится в состоянии ожидания. После завершения обменной операции обработка по программе продолжается.


Рисунок 3.2. Порядок проведения связи при записи и чтении.

В следующем фрагменте кода глобальным указателем *globalgp, имеющем предопределенный тип, благодаря ссылке gp-> вызывается описанная в удаленном процессорном объекте функция p(...), результат выполнения которой присваивается возвращаемой переменной result:

<type> *global gp;

result = gp->p(...);

Приведенный фрагмент представляет собой общую форму записи дистанционного управления, обозначаемого в литературе аббревиатурой RPC (remote procedure call). RPC в процессе выполнения проходит три стадии:

·  Параметры для вызываемой на исполнение функции упаковываются в сообщение, передаются отдаленному процессорному объекту и распаковываются. Вызывающий процесс приостанавливает свое выполнение.

·  Новый процесс, созданный в отдаленном процессорном объекте, выполняет вызванную функцию.

·  После завершения выполнения отдаленной функции ее возвращаемое значение передается обратно в вызвавший ее процесс, который возобновляет прерванное выполнение.

Без вмешательства пользователя параметры для RPC и возвращаемые значения могут иметь следующие базовые типы:

·  целочисленные (char, short, int, long и их варианты без знака – unsigned);

·  действительные (floats, doubles);

·  глобальные указатели.

Структуры, регулярные указатели и массивы могут быть переданы как параметры при помощи функций преобразования типа.

Текст 3.5. – Программа вызова удаленных функций

intlength;                          // Неявно определенная глобальная переменная

globalclassLength   // Описание глобального класса Length

  {                                                  //с функциями read_len() и write_len(),

    public:                   // являющихся общими членами данного класса

int read_len() { return(length);}

void write_len(int newval) { length = newvel;}

  };

// Создание и использование объектов класса Length в программе test()

void test()

{

int len, len2;

// Новый глобальный процессорный объект lp для класса Length

Length *global lp = new Length;

// Запись частной переменной length

lp->write_len(5);

// Чтение частной переменной length

len = lp->read_len();

// Выполнение операций с прочитанным

len2 = len*2;

}

В тексте 3.5  используются удаленные вызовы процедур (RPC-s), чтобы обратиться к переменной length, расположенной в другом процессорном объекте. Связи между процессорными объектами, устанавливаемые в соответствии с текстом 3.5, показаны на рисунке 3.3.

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