MPI的MPI_Barrier()和MPI_Finalize()函数的正确使用方法?
//代码和注释都来自网上,所以注释的内容并不一定正确!
#include "mpi.h"
#include <stdio.h>
#include <math.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char *argv[]){
int myid; // 当前进程的编号
int numprocs; // 当前进程的名称
int namelen;
char processor_name[MPI_MAX_PROCESSOR_NAME];
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&myid);
MPI_Get_processor_name(processor_name,&namelen);
int i;
for(i=0; i<4; ++i){
printf("I'm %d, sending %d\n",myid,i);
if(1 == myid && 0 == i){
MPI_Barrier(MPI_COMM_WORLD); //进程0将一直等待,直到其他并行进程执行结束
}
}
printf("I'm %d, I am waiting.\n",myid);
MPI_Finalize(); //由于未执行MPI_Finalize,进程0无法感知到其他进程已退出
printf("I'm %d, I finished here.\n",myid);
return 0;
}
运行时会停在这里MPI_Finalize()之前?
air:~ wkl$ mpirun -np 3 ./a.out
I'm 0, sending 0
I'm 0, sending 1
I'm 0, sending 2
I'm 0, sending 3
I'm 0, I am waiting.
I'm 1, sending 0
I'm 2, sending 0
I'm 2, sending 1
I'm 2, sending 2
I'm 2, sending 3
I'm 2, I am waiting.
如果删除中间的循环则会正常结束所有进程退出,如下:
air:~ wkl$ mpirun -np 3 ./a.out
I'm 0, I am waiting.
I'm 2, I am waiting.
I'm 1, I am waiting.
I'm 2, I finished here.
I'm 0, I finished here.
I'm 1, I finished here.
air:~ wkl$
关于MPI_Finalize()
,它到底做了什么,MPI_COMM_WORLD
中只要有进程没有执行到这里,它就会阻止所有相关的进程的退出? 还有即使MPI_Finalize()
执行后,进程似乎并没有真正结束,它后面的printf
语句还在每个进程中执行,为什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
MPI_Barrier(MPI_COMM_WORLD);
上面这句应该放在所有程序都可以执行得到的地方,你用了一个条件语句if(1 == myid && 0 == i),也就限制了只有rank=1的进程能够执行MPI_Barrier(MPI_COMM_WORLD);所以rank等于1的进程执行到这句就一直在那等待,等待其他进程都执行到这句再同时继续执行,然而其他线程都不会执行到这句,所以线程1就一直在那等待,等到天荒地老。。。。。。
你把条件语句和barrier两边大括号去掉,编译执行,看运行结果就知道这个函数怎么回事了。。。。。。