Шрифт:
pvm_bufinfo (N, &NumBytes, &MessageId, &Ptid) ; //. . .
switch(MessageId) {
case 1 : // Некоторые действия, break;
case 2 : // Другие действия, break
//. . .
}
В данном случае функци я pvm_bufinfo используетс я дл я получени я информации о последнем сооб щ ении, прин я том в буфер приема N. Мы можем получить количество байтов, идентификатор сооб щ ени я (messageid) и узнать, кто его отправил. Знал значение messageid, мы можем выполнить соответствую щ ие логические действи я. Функци я pvm_send посылает заданной задаче команду псевдоблокировани я, после приема которой задача блокируетс я до тех пор, пока отправитель не убедится в том, что сообщение было послано правиль н о. Задача-отправитель не ожидает реального получени я сооб щ ения. Функция pvm_psend отправляет сооб щ ение непосредственно указанной задаче. Обратите внимание на то, что функция pvmj?send имеет параметр buffer, используемый в качестве буфера для хранения посылаемого сообщения. Функция pvm_mcast используется для отправки сообщения нескольким задачам одновременно. Аргументы, передавае м ые функции pvm _mcast , включают массив идентификаторов задач-получателей сообщения (taskid), количество задач — участников «широковещания» (ntask) и идентификатор сообщения (messageid) для идентификации отправляемого сооб щ ения. На рис. 6.6 показано, что у каждой PVM-задачи есть собственный буфер отправки, который существует в течение про м ежутка вре м ени, длительности которого было бы достаточно, чтобы сообщение гарантированно дошло до адресата.
За исключение м управляющих сообщений, значение сообщений, которы м и обмениваются любые две PVM-задачи, заранее определено логикой конкретного приложения, т.е. назначение каждого сообщения должно быть заранее известно для задачи-отправителя и задачи-получателя. Эти сообщения передаются асинхронно, могут иметь любой тип данных и произвольную длину. Тем са м ы м д ля приложения обеспечивается максимальнал гибкость. Аналога м и отправляе м ых РУМкюоб щ ений являются принимаемые PVM-сооб щ ения. Так, за прие м сооб щ ений «отвечают» пять основных функций.
Синопсис
# inc lude " pvm3 . h»
int pvm_recv(int taskid, int messageid) ;
int pvm_nrecv(int taskid, int messageid) ;
int pvm_precv(int taskid, int messageid, char *buffer,
int size, int type, int sender,
int messagetag, int messagelength); int pvm_trecv(int taskid,int messageid,
struct timeval *timeout); int pvm_probe(int taskid , int messageid);
Функция pvm_recv используется о д ни м и PVM-за д ача м и для получения сооб щ ений от других. Эта функция создает новый активный буфер, предназначенный для хранения полученного сооб щ ения. Пара м етр taskid определяет идентификатор задачи-отправителя. Пара м етр messageid идентифицирует сооб щ ение, которое послано отправителе м. Следует и м еть в виду, что задача м ожет отправить несколько сообщений, и м ею щ их различные или одинаковые идентификаторы (messageid). Если taskid = – 1, то функция pvm_recv при м ет сооб щ е н ие от любой задачи. Ec-лиmessageid = – 1, то функция при м ет любое сооб щ ение. При успешном выполнении функция pvm_recv возвра щ ает идентификатор нового активного буфера, в противном случае — отрицательное значение. После вызова функции pvm_recv задача будет заблокирована и станет ожидать до тех пор, пока сооб щ ение не будет получено. После получения сооб щ ение считывается из активного буфера с помо щ ью одной из функций распаковки, напри м ер:
//...
float Value[10] ; pvm _recv (400002,2) ; pvn_unpkfloat(400002, Value,l) ; cout « Value..
Здесь фу н кция pvm_recv обеспечивае т ожидание сооб щ ения от задачи, идентификатор которой равен 400002. Идентификатор сооб щ ения (messageid), полученно г о от задачи c номером 400002, должен быть равен значению 2. Затем используется функция распаковки для считывания массива чисел с плаваю щ ей точкой типа float. То г да как функция pvm_recv вынуждает задачу ожидать до тех пор, пока она не получит сооб щ ение, функция pvm_nrecv обеспечивает прием сообщений без блокирования. Если соответствующее сообщение не посгупает адресагу, функция pvm_nrecv немедленно завершается. По прибытии сооб щ ения по месту назначени я функци я pvm_nrecv сразу же завершаетс я, а активный буфер будет содержать полученное сооб щ ение. Если произойдет сбой, функция pvm_nrecv возвратит отрицательное значение. Если сооб щ ение не поступит адресату, функция возвратит число 0. Если сооб щ ение бла г ополучно прибудет по месту назначения, функция возвратит номер ново г о активно г о буфера. Параметр taskid содержит идентификатор задачи-отправителя. Параметр messageid содержит идентификатор сооб щ ения, определенный пользователем. Если taskid = – 1, функция pvm_nrecv примет сооб щ ение от любой задачи. Если messageid = – 1, эта функция примет любое сооб щ ение. При прие м е сооб щ ений с помощью функций pvm_recv или pvm_nrecv создается новый активный буфер, а теку щ ий буфер приема очищается.
Тогда как функции pvm_recv , pvm_nrecv и pvm_trecv принимают сооб щ ения в новый активный буфер, функция pvm_precv принимает сооб щ ение непосредственно в буфер, определенный пользователем. Параметр taskid содержит идентификатор задачи-отправителя. Параметр messageid идентифицирует получаемые сооб щ ения. Параметр buffer должен содержать реально принятое сооб щ ение. Поэтому вместо получения сооб щ ения из активного буфера с по м о щ ью одной из функций распаковки, сооб щ ение считывается напрямую из пара м етра buffer. Параметр size содержитдлину сооб щ ения в байтах. Параметр type определяет тип данных, содержа щ ихся в сооб щ ении. Параметр type может иметь следую щ ие значения:
PVM_STR PVM_BYTE
PVM_SHORT PVM_INT
PVM_FLOAT PVM_DOUBLE
PVM_LONG PVM_USHORT
PVM_CPLX PVM_DCPLX
PVM_UINT PVM_ULONG
Функция pvm_trecv позволяет программисту организовать процедуру получения сооб щ ений с ограничением по времени. Эта функция заставляет вызываю щ ую задачу перейти в заблокированное состояние и ожидать прихода сооб щ ения, но лишь в течение промежутка времени, заданного параметром timeout. Этот параметр представляет собой струкгуру типа timeval, определенную в заголовке time.h, например:
#include «pvm3.h» //. . .
struct timeval TimeOut; TimeOut.tv_sec = 1000; int TaskId; int MessageId;
TaskId = pvm_parent; MessageId = 2;
pvro_trecv(TaskId,MessageId, &TimeOut) ; //...
Здесь переменная TimeOut содержит член tv_sec, установленный равным ЮОО с. Структуру timeval можно использовать для установки временных значений в секундах и микросекундах. Структура timeval имеет следую щ ий вид:
struct timeval{
long tv_sec; // секунды
long tv_usec; // микросекунды
};
Этот пример означает, что функция pvm_trecv заблокирует вызываю щ ую задачу максимум на 1000c. Если сооб щ ение будет получено до истечения заданных ЮОО с, функция сразу завершится. Функцию pvm_trecv можно использовать для предотвращения бесконечных задержек и взаимоблокировок. При успешном выполнении функция pvm_trecv( ) возвра щ ает номер нового активного буфера, в противном случае (при возникновении ошибки) — отрицательное значение. Если taskid = -1, функция примет сооб щ ение от любого отправителя. Если messageid = -1, функция примет любое сооб щ ение.