发送和接收的 MPI 死锁
MPI Deadlock with Send and Receive
我的代码是输入数字 a
(下限)和 b
(上限),然后在它们之间输入数字 c
并找到这个数字的位置在范围
当 运行 此代码在 ubuntu 终端上时,它在输入数字 a
b
和 c
后停止 运行ning,我尝试评论发送和恢复行并打印发送语句及其工作之前的位置
但我想找到c
的位置并发送给master进程打印
注意:我认为因为发送和接收是阻塞函数,这可能会导致死锁或类似情况?我不确定,非常感谢对这个问题的任何帮助
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
int main(int argc , char * argv[])
{
int rank,nprocess,tag=0,a,b,c,i=0,*arr,*subArr,arrSize=0,blockSize=0,pos=0,dest;
MPI_Status status;
/* Start up MPI */
MPI_Init( &argc , &argv );
/* Find out process rank */
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
/* Find out number of process */
MPI_Comm_size(MPI_COMM_WORLD, &nprocess);
if(rank==0){
printf("Enter the lower Range and the upper Range : ");
if(scanf("%d",&a)){}; //2
if (scanf("%d",&b)){}; //9
printf("Enter the search number : ");
if(scanf("%d",&c)){}; //5
arrSize=(b-a)+1;
while(arrSize%nprocess!=0)arrSize++; //Enhance the array Size
printf("array size is : %d \n",arrSize);
arr=(int *)malloc(arrSize*sizeof(int));
for(i=0;i<arrSize;i++){
if(i<((b-a)+1))arr[i]=a+i;
else { arr[i]=b;}
}
printf("Array is :");
for(i=0;i<arrSize;i++){
printf("%d ",arr[i]); //2 3 4 5 6 7 8 9 9
}
printf("\n");
blockSize=arrSize/nprocess; //3
for(i=0;i<nprocess;i++){
dest=i;
MPI_Recv (&pos,1,MPI_INT,dest,tag,MPI_COMM_WORLD,&status);
}
printf("The postion of the number %d in the range from %d to %d is : %d \n ",c,a,b,pos);
}
MPI_Bcast (&c,1,MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast (&blockSize,1,MPI_INT,0,MPI_COMM_WORLD);
subArr=(int *) malloc(blockSize*sizeof(int));
MPI_Scatter (arr,blockSize,MPI_INT,subArr,blockSize,MPI_INT,0,MPI_COMM_WORLD);
for(i=0;i<blockSize;i++){
if(subArr[i]==c){
pos=(blockSize+1)*rank;
printf("The Postion is : %d ",pos); // postion is 4 since array is 2 3 4 5 6 7 8 9 9 and I search for 5
MPI_Send (&pos,1,MPI_INT,0,tag,MPI_COMM_WORLD);
break;
}
}
MPI_Finalize();
return 0;
}
的确,这是一个僵局。根进程尝试 MPI_Recv()
来自其他进程的消息,而其他进程在 MPI_Bcast(&c,...)
处被阻塞,期望进程 0 广播某些内容。
在调用 MPI_Bcast()
和 MPI_Scatter()
之后移动 MPI_Recv()
怎么样?
最后,进程 to
上对 MPI_Recv(.,.,.,source,.,.)
的每次调用都必须与进程 source
上对 MPI_Send(.,.,.,to,.,.)
的相应调用相匹配。由于您要查找的数字在数组中只出现一次,因此只调用了一次 MPI_Send(...,0,.)
。因此,进程 0 必须只调用一次 MPI_Recv()
。由于任何进程都可以发送消息,因此必须使用宏 MPI_ANY_SOURCE
而不是 source
。
以下代码已更正。它由 mpicc main.c -o main -Wall
和 运行 由 mpirun -np 3 main
编译。
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
int main(int argc , char * argv[])
{
int rank,nprocess,tag=0,a,b,c,i=0,*arr,*subArr,arrSize=0,blockSize=0,pos=0,deadlock=0;
MPI_Status status;
/* Start up MPI */
MPI_Init( &argc , &argv );
/* Find out process rank */
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
/* Find out number of process */
MPI_Comm_size(MPI_COMM_WORLD, &nprocess);
if(rank==0){
printf("Enter the lower Range and the upper Range : ");fflush(stdout);
if(scanf("%d",&a)){}; //2
if (scanf("%d",&b)){}; //9
printf("Enter the search number : ");fflush(stdout);
if(scanf("%d",&c)){}; //5
arrSize=(b-a)+1;
while(arrSize%nprocess!=0)arrSize++; //Enhance the array Size
printf("array size is : %d \n",arrSize);
arr=(int *)malloc(arrSize*sizeof(int));
for(i=0;i<arrSize;i++){
if(i<((b-a)+1))arr[i]=a+i;
else { arr[i]=b;}
}
printf("Array is :");
for(i=0;i<arrSize;i++){
printf("%d ",arr[i]); //2 3 4 5 6 7 8 9 9
}
printf("\n");
blockSize=arrSize/nprocess; //3
}
MPI_Bcast (&c,1,MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast (&blockSize,1,MPI_INT,0,MPI_COMM_WORLD);
subArr=(int *) malloc(blockSize*sizeof(int));
MPI_Scatter (arr,blockSize,MPI_INT,subArr,blockSize,MPI_INT,0,MPI_COMM_WORLD);
for(i=0;i<blockSize;i++){
if(subArr[i]==c){
pos=(blockSize)*rank+i;
printf("The Postion is : %d ",pos); // postion is 4 since array is 2 3 4 5 6 7 8 9 9 and I search for 5
if(rank==0){
deadlock=1;
break;
}
MPI_Send (&pos,1,MPI_INT,0,tag,MPI_COMM_WORLD);
break;
}
}
if(rank==0){
//for(i=0;i<nprocess;i++){
// dest=i;
if(deadlock==0)
MPI_Recv (&pos,1,MPI_INT,MPI_ANY_SOURCE,tag,MPI_COMM_WORLD,&status);
// }
printf("The postion of the number %d in the range from %d to %d is : %d \n ",c,a,b,pos);
free(arr);
}
free(subArr);
MPI_Finalize();
return 0;
}
我的代码是输入数字 a
(下限)和 b
(上限),然后在它们之间输入数字 c
并找到这个数字的位置在范围
当 运行 此代码在 ubuntu 终端上时,它在输入数字 a
b
和 c
后停止 运行ning,我尝试评论发送和恢复行并打印发送语句及其工作之前的位置
但我想找到c
的位置并发送给master进程打印
注意:我认为因为发送和接收是阻塞函数,这可能会导致死锁或类似情况?我不确定,非常感谢对这个问题的任何帮助
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
int main(int argc , char * argv[])
{
int rank,nprocess,tag=0,a,b,c,i=0,*arr,*subArr,arrSize=0,blockSize=0,pos=0,dest;
MPI_Status status;
/* Start up MPI */
MPI_Init( &argc , &argv );
/* Find out process rank */
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
/* Find out number of process */
MPI_Comm_size(MPI_COMM_WORLD, &nprocess);
if(rank==0){
printf("Enter the lower Range and the upper Range : ");
if(scanf("%d",&a)){}; //2
if (scanf("%d",&b)){}; //9
printf("Enter the search number : ");
if(scanf("%d",&c)){}; //5
arrSize=(b-a)+1;
while(arrSize%nprocess!=0)arrSize++; //Enhance the array Size
printf("array size is : %d \n",arrSize);
arr=(int *)malloc(arrSize*sizeof(int));
for(i=0;i<arrSize;i++){
if(i<((b-a)+1))arr[i]=a+i;
else { arr[i]=b;}
}
printf("Array is :");
for(i=0;i<arrSize;i++){
printf("%d ",arr[i]); //2 3 4 5 6 7 8 9 9
}
printf("\n");
blockSize=arrSize/nprocess; //3
for(i=0;i<nprocess;i++){
dest=i;
MPI_Recv (&pos,1,MPI_INT,dest,tag,MPI_COMM_WORLD,&status);
}
printf("The postion of the number %d in the range from %d to %d is : %d \n ",c,a,b,pos);
}
MPI_Bcast (&c,1,MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast (&blockSize,1,MPI_INT,0,MPI_COMM_WORLD);
subArr=(int *) malloc(blockSize*sizeof(int));
MPI_Scatter (arr,blockSize,MPI_INT,subArr,blockSize,MPI_INT,0,MPI_COMM_WORLD);
for(i=0;i<blockSize;i++){
if(subArr[i]==c){
pos=(blockSize+1)*rank;
printf("The Postion is : %d ",pos); // postion is 4 since array is 2 3 4 5 6 7 8 9 9 and I search for 5
MPI_Send (&pos,1,MPI_INT,0,tag,MPI_COMM_WORLD);
break;
}
}
MPI_Finalize();
return 0;
}
的确,这是一个僵局。根进程尝试 MPI_Recv()
来自其他进程的消息,而其他进程在 MPI_Bcast(&c,...)
处被阻塞,期望进程 0 广播某些内容。
在调用 MPI_Bcast()
和 MPI_Scatter()
之后移动 MPI_Recv()
怎么样?
最后,进程 to
上对 MPI_Recv(.,.,.,source,.,.)
的每次调用都必须与进程 source
上对 MPI_Send(.,.,.,to,.,.)
的相应调用相匹配。由于您要查找的数字在数组中只出现一次,因此只调用了一次 MPI_Send(...,0,.)
。因此,进程 0 必须只调用一次 MPI_Recv()
。由于任何进程都可以发送消息,因此必须使用宏 MPI_ANY_SOURCE
而不是 source
。
以下代码已更正。它由 mpicc main.c -o main -Wall
和 运行 由 mpirun -np 3 main
编译。
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
int main(int argc , char * argv[])
{
int rank,nprocess,tag=0,a,b,c,i=0,*arr,*subArr,arrSize=0,blockSize=0,pos=0,deadlock=0;
MPI_Status status;
/* Start up MPI */
MPI_Init( &argc , &argv );
/* Find out process rank */
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
/* Find out number of process */
MPI_Comm_size(MPI_COMM_WORLD, &nprocess);
if(rank==0){
printf("Enter the lower Range and the upper Range : ");fflush(stdout);
if(scanf("%d",&a)){}; //2
if (scanf("%d",&b)){}; //9
printf("Enter the search number : ");fflush(stdout);
if(scanf("%d",&c)){}; //5
arrSize=(b-a)+1;
while(arrSize%nprocess!=0)arrSize++; //Enhance the array Size
printf("array size is : %d \n",arrSize);
arr=(int *)malloc(arrSize*sizeof(int));
for(i=0;i<arrSize;i++){
if(i<((b-a)+1))arr[i]=a+i;
else { arr[i]=b;}
}
printf("Array is :");
for(i=0;i<arrSize;i++){
printf("%d ",arr[i]); //2 3 4 5 6 7 8 9 9
}
printf("\n");
blockSize=arrSize/nprocess; //3
}
MPI_Bcast (&c,1,MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast (&blockSize,1,MPI_INT,0,MPI_COMM_WORLD);
subArr=(int *) malloc(blockSize*sizeof(int));
MPI_Scatter (arr,blockSize,MPI_INT,subArr,blockSize,MPI_INT,0,MPI_COMM_WORLD);
for(i=0;i<blockSize;i++){
if(subArr[i]==c){
pos=(blockSize)*rank+i;
printf("The Postion is : %d ",pos); // postion is 4 since array is 2 3 4 5 6 7 8 9 9 and I search for 5
if(rank==0){
deadlock=1;
break;
}
MPI_Send (&pos,1,MPI_INT,0,tag,MPI_COMM_WORLD);
break;
}
}
if(rank==0){
//for(i=0;i<nprocess;i++){
// dest=i;
if(deadlock==0)
MPI_Recv (&pos,1,MPI_INT,MPI_ANY_SOURCE,tag,MPI_COMM_WORLD,&status);
// }
printf("The postion of the number %d in the range from %d to %d is : %d \n ",c,a,b,pos);
free(arr);
}
free(subArr);
MPI_Finalize();
return 0;
}