【问题标题】:MPI_Finalize hangs in dynamically spawned processMPI_Finalize 在动态生成的进程中挂起
【发布时间】:2014-03-16 21:43:51
【问题描述】:

我有第一个进程 (test1),它动态生成第二个进程 (test2),然后等待从生成的组接收带有标签 1 的消息。 生成的进程执行一些计算,然后向父组(包含第一个进程)发送带有标签 1 的消息,表示它已经完成,最后调用 MPI_Finalize。 第一个进程正确接收消息并继续,但第二个进程在 MPI_Finalize 中挂起。 我不明白是什么阻止了第二个进程终止。

测试 1

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

int main() {
int flag_mpi, erc, err_mpi, ndr;
MPI_Comm comm;

MPI_Initialized (&flag_mpi);
if (!flag_mpi) MPI_Init (NULL,NULL);

err_mpi = MPI_Comm_spawn("test2", MPI_ARGV_NULL, 1, MPI_INFO_NULL,
        0, MPI_COMM_WORLD, &comm, &erc);

MPI_Recv(&ndr, 1, MPI_INT, 0, 1, comm, MPI_STATUS_IGNORE);
printf("  Spawn_recv ok (ndr=%d)\n", ndr);

int i = 1;
while (i == 1) {  /* just to simulate further computation */
    printf(".");
    sleep(5);
}

MPI_Initialized (&flag_mpi);
if (flag_mpi) MPI_Finalize();
return 0;
}

测试 2

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

int main() {
int ndr;
MPI_Comm comm;
MPI_Init (NULL,NULL);

    /* some computation not involving MPI */

MPI_Comm_get_parent(&comm);

ndr = 1;
MPI_Send(&ndr, 1, MPI_INT, 0, 1, comm);
printf("  Spawn_sent ok (ndr=%d)\n", ndr);

MPI_Finalize();
return 0;
}

【问题讨论】:

    标签: c mpi


    【解决方案1】:

    在您的 while 循环中,i 不会改变。这将解释您的代码永远不会结束。看来您的代码适用于mpiexec -n 1 test1

    如果您使用mpiexec -n 2 test1,则会创建两个进程,并且进程 0 会生成第三个。问题是第二个进程会等待消息...

    我建议修改:

     int rank;
     MPI_Comm_rank(MPI_COMM_WORLD,&rank);
     if(rank==0){
         MPI_Recv(&ndr, 1, MPI_INT, 0, 1, comm, MPI_STATUS_IGNORE);
         printf("  Spawn_recv ok (ndr=%d)\n", ndr);
     }
    

    还有类似的:

     int i = 30;
     while (i != 1) {  /* just to simulate further computation */
         printf(".");
         sleep(1);
         i--;
     }
    

    编辑:我误解了这个问题...所以这里有一个更好的答案:您可以在 test1.c 和 test2.c 中添加 MPI_Comm_disconnect(&amp;comm); 以关闭进程之间的连接!这样,生成的进程将不会等待第一个通过MPI_Finalize()...

    http://www.mcs.anl.gov/research/projects/mpi/www/www3/MPI_Comm_disconnect.html

    再见,

    弗朗西斯

    【讨论】:

    • 我只是在运行mpiexec -n 1 test1,所以第一组中应该没有其他进程在等待消息。我尝试了您的修改,但生成的进程仍然挂在 MPI_Finalize 中,而我希望它在第一个进程进入 while 循环后终止该循环本来不会完成,所以我有时间启动 gdb 并查看发生了什么(然后将变量i 设置为不同的值并让进程终止)。但是您的解决方案也很好。
    • @vlxm:我为我的误解道歉!你可以使用MPI_Comm_disconnect(&amp;comm);
    猜你喜欢
    • 2019-03-22
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 2020-09-03
    • 2012-09-26
    • 1970-01-01
    • 2020-07-06
    • 1970-01-01
    相关资源
    最近更新 更多