MPI中的简单聊天程序C ++

时间:2017-04-07 14:11:55

标签: c++ mpi

我的程序包括一个服务器级别进程和一个客户端级别进程。客户端将一个数字(Double类型的数组)传输到服务器。

这是我的代码

//Server rank
if (rank == 0){
    double buf[MAX_DATA];
    MPI_Open_port(MPI_INFO_NULL, port_name);
    printf("server available at %s\n", port_name);

    while (1) {
        MPI_Comm_accept(port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &client);
        again = 1;
        while (again) {
            MPI_Recv(buf, MAX_DATA, MPI_DOUBLE, 0, MPI_ANY_TAG, client, &status);

            switch (status.MPI_TAG) {
            case 0: 
                MPI_Comm_free(&client);
                MPI_Close_port(port_name);
                MPI_Finalize();
                return 0;
            case 1:
                MPI_Comm_disconnect(&client);
                again = 0;
                break;
            case 2: /* do something */
                printf("case 2\n");
                break;
            default:
                /* Unexpected message type */
                MPI_Abort(MPI_COMM_WORLD, 1);
            }
        }
    }
}
// client rank
else
{
    MPI_Comm server;
    double buf[MAX_DATA];
    MPI_Comm_connect(port_name, MPI_INFO_NULL, 0, MPI_COMM_WORLD, &server);
    int i = 0;
    while (true) {
        int tag = 2; /* Action to perform */
        MPI_Send(buf, MAX_DATA, MPI_DOUBLE, 0, tag, server);
    }
    MPI_Send(buf, 0, MPI_DOUBLE, 0, 1, server);
    MPI_Comm_disconnect(&server);
}

MPI_Finalize();

但代码不起作用,当我输入命令时它被卡住了 “mpiexec -n 2 MPI_HelloWorld.exe”(创建了2个运行该程序的进程)

我修改了此来源的代码:“http://www.mcs.anl.gov/research/projects/mpi/mpi-standard/mpi-report-2.0/node106.htm

程序的结果:它卡住了:服务器没有收到消息 enter image description here

1 个答案:

答案 0 :(得分:1)

少数事情:

1)服务器需要告诉客户端它将接受通信的端口。因此,在开始接受之前需要向客户端发送消息并告诉客户端此port_name。

所以,需要这样的电话:

MPI_Send(port_name, MPI_MAX_PORT_NAME, MPI_CHAR, 1, 0, MPI_COMM_WORLD);

客户端需要收到此消息。所以,客户首先要做的是:

MPI_Recv(port_name, MPI_MAX_PORT_NAME, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);

2)由于客户端/服务器需要点对点通信(您可以拥有多个客户端,但同时只能在两个进程之间),因此我们无法使用MPI_Comm_World(包括所有进程)在MPI_Comm_accept()MPI_Comm_connect()中。要使用的正确沟通者是MPI_COMM_SELF

因此需要将这些调用更改为:

MPI_Comm_accept(port_name, MPI_INFO_NULL, 0, MPI_COMM_SELF, &client);

MPI_Comm_connect(port_name, MPI_INFO_NULL, 0, MPI_COMM_SELF, &server);

以下代码已在我的系统上测试并运行:

#include <stdio.h>
#include <mpi.h>
#define MAX_DATA    100

int main (int argc, char *argv[]){

  int rank, size;
  char port_name[MPI_MAX_PORT_NAME];

  MPI_Init (&argc, &argv);  /* starts MPI */
  MPI_Comm_rank (MPI_COMM_WORLD, &rank);    /* get current process id */
  MPI_Comm_size (MPI_COMM_WORLD, &size);    /* get number of processes */

  //Server rank
  if (rank == 0){
    double buf[MAX_DATA];
    MPI_Open_port(MPI_INFO_NULL, port_name);
    printf("server available at %s\n", port_name);

    // server tells the client about the port_name
    MPI_Send(port_name, MPI_MAX_PORT_NAME, MPI_CHAR, 1, 0, MPI_COMM_WORLD);
    MPI_Comm client;
    MPI_Status status;
    while (1) {
        MPI_Comm_accept(port_name, MPI_INFO_NULL, 0, MPI_COMM_SELF, &client);
        int again = 1;
        while (again) {
            MPI_Recv(buf, MAX_DATA, MPI_DOUBLE, 1, MPI_ANY_TAG, client, &status);
            printf("server received sth!\n");   
            switch (status.MPI_TAG) {
            case 0: 
                MPI_Comm_free(&client);
                MPI_Close_port(port_name);
                MPI_Finalize();
                return 0;
            case 1:
                MPI_Comm_disconnect(&client);
                again = 0;
                break;
            case 2: /* do something */
                printf("case 2\n");
                break;
            default:
                /* Unexpected message type */
                MPI_Abort(MPI_COMM_WORLD, 1);
            }
        }
    }
  } else{
    MPI_Status status;
    // client receives the port information from server
    MPI_Recv(port_name, MPI_MAX_PORT_NAME, MPI_CHAR, 0, 0, MPI_COMM_WORLD, &status);

    MPI_Comm server;
    double buf[MAX_DATA];

    MPI_Comm_connect(port_name, MPI_INFO_NULL, 0, MPI_COMM_SELF, &server);
    int i = 0;
    while (1) {
        int tag = 2; /* Action to perform */
        MPI_Send(buf, MAX_DATA, MPI_DOUBLE, 0, tag, server);
        printf("client send somthing!\n");
        sleep(1);
    }
    MPI_Send(buf, 0, MPI_DOUBLE, 0, 1, server);
    MPI_Comm_disconnect(&server);
  }

  MPI_Finalize();
}