Part 5: Adding Parallel Programming Capabilities to C++ Through the PVM

Synopsis

#include "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);

The pvm_recv() routine is used to receive messages from other PVM tasks. This routine creates a new active buffer that will contain the message received. The taskid parameter specifies the task identifier of the sending task. The messageid parameter identifies the message that is being sent from the sender. Keep in mind that a task may send multiple messages each with different or the same messageid . If the taskid = -1 then the pvm_recv() routine will accept a message from any task. If the messageid parameter = -1 then the routine will accept any message. The pvm_recv() routine return value will be the buffer id of the new active buffer if the call is successful and will be a value < 0 if an error has occurred. When a task calls the pvm_recv() routine will block and wait until the message has been received. After the message is received, it is retrieved from the active message buffer using one of the unpack routines. For instance:

//...

float Value[10];

pvm_recv(400002,2);

pvm_unpkfloat(400002, Value,1);

cout << Value..

The pvm_recv() routine causes this code to wait on a message from a task identified as 400002. The messageid received from 400002 must be 2 before the routine unblocks. The unpack routine is then used to retrieve the array of float s. Whereas the pvm_recv() routine causes the task to wait until it receives a message, the pvm_nrecv() routine is a non-blocking receive. If the appropriate message has not arrived, the pvm_nrecv() routine will immediately return. If the message has arrived, the pvm_nrecv() will return immediately and the active buffer will contain the message. If an error condition occurs then pvm_nrecv() will return a value < 0 . If the message has not arrived the routine returns 0 . If the message has arrived, the number for the new active buffer will be returned. The taskid parameter will contain the task identifier for the sending task. The messageid parameter will contain a user-defined message id. If the taskid = -1 then the pvm_nrecv() routine will accept a message from any task. If the messageid = -1 then the routine will receive any message. When messages are received in the active buffer by either pvm_recv() or pvm_nrecv() a new active buffer is created and the current receive buffer is cleared.

Whereas the pvm_recv() , pvm_nrecv() , and the pvm_trecv() receive their messages into a new active buffer, the pvm_precv() routine receives its message directly into a user-defined buffer. The taskid parameter contans the task identifier for the sending task. The messageid parameter identifies which message is being received. The buffer parameter will contain the actual message. So instead of getting the message from the active buffer using one of the unpack routines, the message is retrieved directly from the buffer parameter. The size parameter contains the length in bytes of the message. The type parameter specifies the data type of the message. The values for data type are:

PVM_STR PVM_BYTE

PVM_SHORT PVM_INT

PVM_FLOAT PVM_DOUBLE

PVM_LONG PVM_USHORT

PVM_CPLX PVM_DCPLX

PVM_UINT PVM_ULONG

The pvm_trecv() is an important routine that allows the programmer to use a timed receive. The pvm_trecv() routine causes the calling task to block and wait for the message but only for the amount of time specified timeout parameter. The specified parameter is a structure of type timeval defined time.h. For example:



#include "pvm3.h"

 //...

 struct timeval TimeOut;
 TimeOut.tv_sec = 1000;
 int TaskId;
 int MessageId;
 TaskId = pvm_parent();
 MessageId = 2;
 pvm_trecv(TaskId,MessageId,&TimeOut);
 //...

the TimeOut variable has the tv_sec member set to 1000 seconds. The timeval struct can be used to set the time out values in seconds and microseconds. The timeval is a struct has the structure:


struct timeval{
   long tv_sec;  // seconds
   long tv_usec; // microseconds
};


This means the pvm_trecv() routine will block the calling task for at most 1000 seconds. If this message gets there before the 1000 seconds have expired the routine will return. This routine can be used to help prevent indefinite postponement and deadlock. If pvm_trecv() is successful it will return the number of the new active buffer. If an error occurs then a value < 0 will be returned. If taskid = -1 the routine will accept a message from any sender. If the messageid parameter = -1 it will accept any message.





Sample chapter, summaries, captions, table of contents, code example and listings are provided for your information. Copyright 2003 Addison Wesley. All rights reserved. No part of these materials may be duplicated or reproduced, in any form or by any means, without the written permission of the publisher.