C 主从非阻塞侦听器

C 主从非阻塞侦听器,c,mpi,nonblocking,master-slave,C,Mpi,Nonblocking,Master Slave,目前,我正在尝试创建一个主从程序,其中包含一个“侦听器”循环,在该循环中,主程序等待来自从程序的消息,以便从那里做出决定。但是,尽管使用了非阻塞MPI例程,我还是遇到了一个错误。我需要使用一些阻塞例程吗 #include "mpi.h" #include <stdio.h> #include <stdlib.h> #include <time.h> int main(int argc, char** argv) { // Variable Declara

目前,我正在尝试创建一个主从程序,其中包含一个“侦听器”循环,在该循环中,主程序等待来自从程序的消息,以便从那里做出决定。但是,尽管使用了非阻塞MPI例程,我还是遇到了一个错误。我需要使用一些阻塞例程吗

#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(int argc, char** argv)
{
  // Variable Declarations
  int rank, size;
  MPI_Request *requestList,requestNull;
  MPI_Status  status;
  // Start MPI
  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &size);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);

  if( rank == 0 )
  {
    // Process Zero
    int   dataOut=13, pr;
    float dataIn = -1;
    requestList =(MPI_Request*)malloc((size-1)*sizeof(MPI_Request));

    while(1){
      dataIn = -1;
      // We do NOT  need to wait for the MPI_ Isend(s), it is the job of the receiver  processes.
      for(pr=1;pr<size;pr++)
      {
        MPI_Irecv(&dataIn,1,MPI_FLOAT,pr,1,MPI_COMM_WORLD,&(requestList[pr-1]));
      }
      if((dataIn > 1.5)){
        printf("From the process: %f\n", dataIn);
        break;
      }
    }
  }
  else
  {
    // Receiver Process
    float message;
    int index;
    //MPI_Request request;
    MPI_Status  status;

    while(1){
      message = random()/(double)1147483648;
      // Send the message back to the process zero
      MPI_Isend(&message,1,MPI_FLOAT,0,1,MPI_COMM_WORLD, &requestNull);

      if(message > 1.5)
      break;
    }
  }
  MPI_Finalize();
  return 0;
}
#包括“mpi.h”
#包括
#包括
#包括
int main(int argc,字符**argv)
{
//变量声明
int等级、大小;
MPI_请求*请求列表,请求空;
MPI_状态;
//启动MPI
MPI_Init(&argc,&argv);
MPI_通信大小(MPI_通信世界和大小);
MPI通信等级(MPI通信世界和等级);
如果(秩==0)
{
//进程零
int-dataOut=13,pr;
浮点数据输入=-1;
请求列表=(MPI_请求*)malloc((大小-1)*sizeof(MPI_请求));
而(1){
dataIn=-1;
//我们不需要等待MPI_uiSend,它是接收方进程的工作。
对于(pr=1;pr 1.5)){
printf(“来自进程:%f\n”,数据输入);
打破
}
}
}
其他的
{
//接收过程
浮动消息;
整数指数;
//MPI_请求;
MPI_状态;
而(1){
message=random()/(双精度)1147483648;
//将消息发送回进程0
MPI_Isend(&message,1,MPI_FLOAT,0,1,MPI_COMM_WORLD,&requestNull);
如果(消息>1.5)
打破
}
}
MPI_Finalize();
返回0;
}

问题似乎在于,您从未等待MPI调用完成

MPI中非阻塞调用的工作方式是,当发出非阻塞调用(如
MPI\u IRECV
)时,最后一个输入参数是
MPI\u请求
对象。当初始化调用(
MPI\u IRECV
)完成时,该请求对象包含非阻塞调用的信息。但是,该调用尚未完成,在您对请求使用完成调用(
MPI\u WAIT
/
MPI\u TEST
/和朋友)之前,您无法保证调用已完成

在您的情况下,您可能不必要地使用了非阻塞调用,因为您依赖于下一行的
MPI_IRECV
调用期间接收到的信息。您可能只需将非阻塞调用替换为阻塞的
MPI\u RECV
调用,并使用
MPI\u ANY\u SOURCE
,这样您就不必为通信器中的每个列组发布单独的接收调用。或者,您可以使用
MPI_WAITANY
来完成非阻塞调用,但是在完成后,您需要担心清理所有额外的操作