C-如何用MPI终止信号

  • 本文关键字:终止 信号 MPI 何用 c mpi
  • 更新时间 :
  • 英文 :


这是我在C中使用MPI编写的第一个程序,该程序应该在15秒内终止,但事实并非如此。它甚至没有通过IF(end_now == 1(语句。有人知道这里发生了什么吗?该代码如下所示:

int end_now = 0;

void sig_handler(int signo)
{
    if (signo == SIGUSR1) {
        end_now = 1;
        printf ( "  %8d  %8dn", current_number, current_total);
    }
}
int main ( int argc, char **argv ){
   int id;
   int count;
   MPI_Init (&argc, &argv);
   MPI_Comm_size (MPI_COMM_WORLD, &count);
   MPI_Comm_rank (MPI_COMM_WORLD, &id);
   signal(SIGUSR1, sig_handler);

   while (1){
       //MPI_Allreduce is called here to sum up the subtotal calculated by child processes
        if (end_now == 1){
            printf("heren");  //this "here is never printed out"
            break;
        }
    }
    MPI_Finalize ();
    return 0;
}

我正在使用timeout -signal = usr1 15 mpirun.openmpi -np 2 ./a.out在我的Mac上执行代码。感谢任何人可能会有所帮助。

您将信号发送给mpirun,而不是可执行文件。由于mpirun本身没有SIGUSR1处理程序,因此什么也不会发生。

顺便说一句,使用MPI程序的信号不是您想做的。MPI程序依赖于在锁定中运行的多个调用,这与信号的异步性和程序性质不符。

sneftel是正确的。Gilles Gouaillardet也很正确。我想添加其他一些信息。

即使您将信号发送到实际程序而不是" Mpirun",也可能将其发送到您的一个流程中,而不是将其发送给所有程序。

是的,在MPI程序中,信号是不对的。但是,即使您想使用它们,您也应该首先调试任何程序以及谁获得它们。

直接将" printf"插入信号处理程序中。打印诸如" MPI Process%d获得信号"之类的东西,然后将MPI_COMM_RANK插入此printf。(UPD 2018-04-27 7:31 MSK:对不起,我没有注意到您已经在您的中有这样的printf((注意:我认为仅在第一个过程中允许的MPI程序中的" printf",而在其他过程中使用" printf"可能是坏主意,但是出于调试目的而言,我认为直接从信号中使用" printf"处理程序是个坏主意,但同样,出于调试的目的,将会进行。(

您将确定您的流程是否获得信号以及其中的信号。

如果您对结果不满意,请尝试不同的程序而不是GTIMEOUT。例如,GNU Coreutils的"超时"。(嗯,这是Mac,我不确定,GNU Coreutils是否可用Mac,但我仍然认为您可以找到一些"超时"。(

然后:您没有描述您的设置。您的MPI程序是否在不同的主机上运行?MPI"程序"是否真的作为单独的程序或线程实现?您使用哪个MPI实现以及哪个版本?如果您不知道MPI如何启动您的流程,至少说我们,您如何安装MPI实现以及如何配置。

,甚至您都无需任何"超时"或" gtimeout"。只需在一个控制台中输入此内容:

sh -c 'echo $$ > ~/pid-of-mpirun; exec ~/opt/usr/local/bin/mpirun -np 2 ./a.out'

这将运行" Mpirun",同时将其PID存储到〜/PID-MPIRUN中。并在另一个终端并行运行(当然,您不需要在同一时刻完全运行此命令(:

sleep 15; kill -USR1 $(cat ~/pid-of-mpirun)

这将需要15秒,然后发送USR1处理哪个PID在〜/pid-mpirun中。

,但所有这些都可能将USR1发送到" Mpirun",而不是将其发送到实际过程(我不确定,测试此!(。如何发送到实际流程?好吧,您可以阅读"杀死"的手册页面,并尝试了解如何将信号发送给整个过程组而不只是一个过程。

另外,您可以将PID直接写入C程序中的某些文件。

示例:

#include <stdio.h>
#include <unistd.h> // Mac is one of UNIX systems, so we have unistd.h
// ...
FILE *fout = fopen("~/my-pid", "w"); fprintf(fout, "%dn", getpid); fclose(fout);

当然,您应该以某种方式确保在不同的过程中创建不同的文件。例如,从mpi_comm_rank生成文件名。

end_now也应声明为volatile,否则编译器可能会优化将永远运行的主循环。

我推荐在信号处理程序中不使用printf,因为printf不可重新输入功能,这可能会导致某些平台上的程序崩溃。

最新更新