我刚刚花了很长时间为别人的问题编写了一篇长答案,但在我发布答案之前就被删除了。我不想浪费这份努力,所以我在这里发布问题和答案。
这不仅是关于发送/接收死锁的标准答案,因为我还发现了一个有趣的半解决方案,它只适用于某些编译器
在并行课程中,我们需要根据主从设计模式进行练习,其中主进程0向所有从进程发送消息,这些从进程将重新将消息发送给它们的右侧和左侧邻居(处理器id +/- 1,除了没有左侧邻居的处理器0和没有右侧邻居的最后一个处理器id)。在将消息转发给邻居之后,从进程向主进程发送确认作业已完成的信息。
这个练习很简单,但我的代码有一个问题,因为我在程序开始时就收到了确认结束消息...我不知道问题出在哪里。我尝试使用fflush,但实际上程序的最后一行应该在接收完成后才写入控制台。
有人有任何想法吗?我对MPI/C概念还很陌生,所以可能我所做的有问题?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>
int main(int argc, char *argv[]){
int np, myId;
char send[100], recv[100];
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &np);
MPI_Comm_rank(MPI_COMM_WORLD, &myId);
MPI_Status stat;
if(myId == 0){
int t = sprintf(send, "hey!"); //MPI_get_processor_name
for(int i = 1; i < np; i++){
printf("send %d => %d\n", myId, i);
fflush(stdout);
MPI_Send(send, 50, MPI_CHAR, i, 0, MPI_COMM_WORLD);
}
for(int i = 1; i < np; i++){
MPI_Recv(recv, 50, MPI_CHAR, i, 0, MPI_COMM_WORLD, &stat);
printf("%s\n", recv);
fflush(stdout);
}
}else{
if(myId < (np - 1)){
printf("send %d => %d\n", myId, myId + 1);
fflush(stdout);
MPI_Send(send, 50, MPI_CHAR, myId + 1, 0, MPI_COMM_WORLD);
}
if(myId > 1){
printf("Envoie %d => %d\n", myId, myId - 1);
fflush(stdout);
MPI_Send(send, 50, MPI_CHAR, myId - 1, 0, MPI_COMM_WORLD);
}
MPI_Recv(send, 50, MPI_CHAR, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &stat);
printf("Réception %d <= %d\n", myId, 0);
fflush(stdout);
if(myId != (np - 1)){
MPI_Recv(send, 50, MPI_CHAR, myId + 1, 0, MPI_COMM_WORLD, &stat);
printf("Receive %d <= %d\n", myId, myId + 1);
fflush(stdout);
}
if(myId != 1){
MPI_Recv(send, 50, MPI_CHAR, myId - 1, 0, MPI_COMM_WORLD, &stat);
printf("Receive %d <= %d\n", myId, myId - 1);
fflush(stdout);
}
int t = sprintf(recv, "End for %d.", myId);
MPI_Send(recv, 50 , MPI_CHAR, 0, 0, MPI_COMM_WORLD);
}
MPI_Finalize();
return 0;
}