主进程打印从进程的消息
#include <stdio.h>
#include "mpi.h"
int main( argc, argv )
int argc;
char **argv;
{
int rank, size;
MPI_Init( &argc, &argv );
MPI_Comm_rank( MPI_COMM_WORLD, &rank );
if (rank == 0)
master_io(); /*进程0作为主进程*/
else
slave_io(); /*其它进程作为从进程*/
MPI_Finalize( );
}
#define MSG_EXIT 1
#define MSG_PRINT_ORDERED 2 /*定义按续打印标识*/
#define MSG_PRINT_UNORDERED 3 /*定义乱续打印标识*/
/* 下面的函数为主进程执行的部分 */
int master_io( void )
{
int i,j, size, nslave, firstmsg;
char buf[256], buf2[256];
MPI_Status status;
MPI_Comm_size( MPI_COMM_WORLD, &size );/*得到总的进程数*/
nslave = size - 1;/*得到从进程的进程数*/
while (nslave > 0) {/* 只要还有从进程,则执行下面的接收与打印*/
MPI_Recv( buf, 256, MPI_CHAR, MPI_ANY_SOURCE, MPI_ANY_TAG,
MPI_COMM_WORLD, &status );/*从任意从进程接收任意标识的消息*/
switch (status.MPI_TAG) {
case MSG_EXIT: nslave--; break;/*若该从进程要求退出,则将总的从进程个数减1*/
case MSG_PRINT_UNORDERED:/*若该从进程要求乱续打印,则直接将该消息打印*/
fputs( buf, stdout );
break;
case MSG_PRINT_ORDERED:/*从进程要求按续打印,这种打印方式处理起来复杂一些,首先需要对收到的消息进行排序,若有些消息还没有收到,则需要调用接收语句接收相应的有序消息*/
firstmsg = status.MPI_SOURCE;
for (i=1; i<size; i++) {/*标识号从小到大开始打印*/
if (i == firstmsg)
fputs( buf, stdout );/*若接收到的消息恰巧是需要打印的消息,则直接打印*/
else {/* 否则,先接收需要打印的消息,然后再打印*/
MPI_Recv( buf2, 256, MPI_CHAR, i, MSG_PRINT_ORDERED,
MPI_COMM_WORLD, &status );/*注意这一接收语句指定了源进程和消息标识,而不是象一开始的那样用任意源和任意标识*/
fputs( buf2, stdout );
}
}
break;
}
}
}
/*下面的函数为从进程执行的部分*/
int slave_io( void )
{
char buf[256];
int rank;
MPI_Comm_rank( MPI_COMM_WORLD, &rank );/*得到自己的标识*/
sprintf( buf, "Hello from slave %d,ordered print\n", rank
);
MPI_Send( buf, strlen(buf) + 1, MPI_CHAR, 0, MSG_PRINT_ORDERED,
MPI_COMM_WORLD );/*先向主进程发送一个有序打印消息*/
sprintf( buf, "Goodbye from slave %d, ordered print\n", rank
);
MPI_Send( buf, strlen(buf) + 1, MPI_CHAR, 0, MSG_PRINT_ORDERED,
MPI_COMM_WORLD );/*再向主进程发送一个有序打印消息*/
sprintf( buf, "I'm exiting (%d),unordered print\n", rank
);
MPI_Send( buf, strlen(buf) + 1, MPI_CHAR, 0, MSG_PRINT_UNORDERED,
MPI_COMM_WORLD );/*最后,向主进程发送一个乱续打印消息*/
MPI_Send( buf, 0, MPI_CHAR, 0, MSG_EXIT, MPI_COMM_WORLD );/*向主进程发送退出执行的消息*/
}
讲解:
主进程(进程0)接收从进程(其它所有进程)的消息,根据消息的不同,分两种方式将消息打印,1是按从进程结点编号的大小依次打印;2是以任意的顺序打印。而从进程则实现向主进程发送消息的任务,消息也分两种:即以任意顺序打印的消息和按进程编号的顺序打印的消息。
|