这是我在c中用MPI编写的第一个程序,该程序应该在15秒内终止,但事实并非如此。它甚至没有通过if(end_now == 1)语句。有谁知道这里发生了什么?代码简化如下:
int end_now = 0;
void sig_handler(int signo)
{
if (signo == SIGUSR1) {
end_now = 1;
printf ( " %8d %8d\n", 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("here\n"); //this "here is never printed out"
break;
}
}
MPI_Finalize ();
return 0;
}
我正在使用超时--signal = USR1 15 mpirun.openmpi -np 2 ./a.out来执行我的Mac上的代码。 感谢任何可能提供帮助的人。
答案 0 :(得分:1)
您正在向mpirun
发送信号,而不是您的可执行文件。由于mpirun
本身没有SIGUSR1
处理程序,因此没有任何反应。
答案 1 :(得分:1)
Sneftel是对的。 Gilles Gouaillardet也很对。我想补充一些其他信息。
即使您将信号发送到实际程序而不是“mpirun”,那么您可能只将其发送到您的进程的ONE而不是所有进程。
是的,在MPI计划中,信号是不正确的。但即使你想使用它们,你也应该首先调试获得它们的任何进程以及它们中的哪些进程。
将“printf”直接插入信号处理程序。打印类似“MPI进程号%d得到信号”并将MPI_COMM_RANK插入此printf。(UPD 2018-04-27 7:31 MSK:对不起,我没注意到你已经有{{1}在你的代码中。)(注意:我认为MPI程序中的“printf”只允许在第一个进程中使用,并且在其他进程中使用“printf”可能是个坏主意,但是出于调试的目的,我会认为是“printf”。 “直接来自信号处理程序是个坏主意,但是,再次,出于调试目的,将继续。”
您将确定您的流程是否获得信号以及哪些信号。
如果您对结果不满意,请尝试使用不同的程序而不是gtimeout。例如,GNU Coreutils的“超时”。 (嗯,这是Mac,我不确定,GNU Coreutils可以在Mac上使用,但我仍然认为你可以找到一些“超时”。)
然后:你没有描述你的设置。您的MPI程序是在不同的主机上还是在一台主机上运行? MPI“程序”真的是作为单独的程序还是作为线程实现的?您使用哪种MPI实现以及哪个版本?如果您不知道MPI如何启动您的流程,至少要说明我们,您如何安装MPI实现以及如何配置它。
甚至你可以在没有任何“超时”或“gtimeout”的情况下完成任务。只需在一个控制台中输入:
printf
这将在将其PID存储到〜/ pid-of-mpirun时运行“mpirun”。并在另一个终端中并行运行(当然,您不需要在同一时刻完全运行此命令):
sh -c 'echo $$ > ~/pid-of-mpirun; exec ~/opt/usr/local/bin/mpirun -np 2 ./a.out'
这需要15秒并发送USR1来处理哪个PID在〜/ pid-of-mpirun中。
但所有这些可能会将USR1发送到“mpirun”而不是实际进程(我不确定,测试一下!)。如何发送到实际流程?那么,您可以阅读“kill”的手册页,并尝试了解如何向整个流程组发送信号,而不是仅仅针对一个流程。
此外,您可以直接在C程序中将PID写入某个文件。
示例:
sleep 15; kill -USR1 $(cat ~/pid-of-mpirun)
当然,您应该以某种方式确保在不同的进程中创建不同的文件。例如,从MPI_COMM_RANK生成文件名。
答案 2 :(得分:0)
end_now
也应声明为volatile
,否则编译器可能会优化将永远运行的主循环。
答案 3 :(得分:0)
我建议不要在信号处理程序中使用printf,因为printf是不可重入的函数,在某些平台上这可能导致程序崩溃。