Параллельное и распределенное программирование на С++
Шрифт:
int pvm_pkshort(short *np, int count, int std) ; Строки:
int pvm_pkstr(char *cp) ;
Все функции упаковки, перечисленные в табл. 6.3, используются для сохранения массиваданных в буфере отправки. Обратите вни м ание на то, что каждая PVM-задача (см. рис.6.6) должна и м еть по крайней м ере один буфер отправки и один буфер приема. Каждал функция упаковки прини м ает указатель на м ассив соответствую щ его типаданных. Все функции упаковки, за исключением функции pvm_pkstr , принимают общее количество элементов, подлежащих сохранению в массиве (а не количество байтов!). Для функции pvm_pkstr предполагается, что символьный массив, с которым она работает, завершается значение м NULL. Каждал функция упаковки, за исключением функции pvm_pkstr, в качестве последнего пара м етра прини м ает значение, которое представляет способ обхода элементов исходного массива при их упаковке в буфер отправки. Этот параметр часто называют шагом по индексу (stride). Например, если
Формат XDR (External Z>ata .Representation) — это стандарт, используемый для описания и шифрования данных. Слелует иметь в виду, что компьютеры, включенные всрелу PVM, могут быть совершенно разными, т.е. среда PVM, например, может состоять из Sun-, Macintosh-, Crays- и AMD-компьютеров. Эти компьютеры могут отличаться размерами машинных слов и по-разному сохранять различные типы данных. В некоторых случалх компьютеры могут различаться и битовой организацией. Стандарт XDR позволяет компьютерам обмениваться данными вне зависимости от типа их архитектуры. Формат Raw используется для отправки данных в собственно м фор м ате компьютера-отправителя. При это м никакое специальное кодирование не при м еняется. Формат In Place в действительности не требует упаковки данных в буфере отправки, и адресату отправляются лишь указатели на данные и раз м ер данных. В это м случае задача-получатель напря м ую копирует данные. В библиотеке PVM эти три типа кодирования данных представляются соответствующи м и тре м я константа м и:
PvmDataDefault XDR
PvmDataRaw Без специального кодирования
PvmDataInPlace В буфер отправки копируются лишь указатели и раз м ер данных
Вот пример: int BufferId;
BufferId = pvm_initsend(PvmDataRaw); //.. .
Здесь константа PvmDataRaw, переданнал функции pvm_initsend в качестве параметра, означает, что данные упаковываются в буфер как есть, т.е. без специально г о кодирования. При успешном выполнении функция возвра щ ает номер буфера отправки (в данном случае он будет записан в переменную BufferId). Важно помнить, что хотя в каждый момент времени активным может быть только один буфер отправки, Любая PVM-задача может иметь несколько таких буферов, и с каждым из них связывается некоторый идентификационный номер.
В библиотеке PVM прелусмотрено несколько функций, имею щ их отношение к процелуре отправки.
Синопсис
# include « pvm3 .h»
int pvm_send(int taskid, int messageid); int pvm_psend(int taskid, int messageid,
char *buffer,int len, int datatype); int pvm_mcast(int *taskid,int ntask,int messageid);
В каждой из этих функций параметр taskid представл я ет собой идентификатор PVM-задачи, которая принимает сооб щ ение. При вызове функции pvm_mcast параметр taskid означает коллекцию задач, представл я емых идентификаторами, которые передаютс я в массиве *taskid. Параметр messageid указывает идентификатор посылаемо г о сооб щ ени я. Идентификаторы сооб щ ений представл я ют собой целочисленные значени я, определенные пользователем. Они используются отправителем и получателем дл я идентификации сооб щ ени я, например:
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-задачи есть собственный буфер отправки, который существует в течение про м ежутка вре м ени, длительности которого было бы достаточно, чтобы сообщение гарантированно дошло до адресата.
За исключение м управляющих сообщений, значение сообщений, которы м
Синопсис
# 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, например: