在 MPI 应用程序中处理信号/正常退出
Handling Signals in an MPI Application / Gracefully exit
如何在 MPI 应用程序中处理信号(例如SIGUSR1应该告诉应用程序其运行时已过期并应在接下来的 10 分钟内终止。我有几个限制:
- 首先完成所有并行/串行IO以退出应用程序!
- 在所有其他情况下,应用程序可以毫无问题地退出
如何安全地实现这一点,在尝试退出时没有死锁,并正确离开当前上下文跳回main()
并调用MPI_FINALIZE()
?不知何故,进程必须在退出时聚合(我认为这在多线程应用程序中是相同的),但是如何在不必与太多通信的情况下有效地完成呢?有没有人知道一些标准的方法可以正确地做到这一点?
以下是一些可能有效也可能无效的想法:
想法1:
假设对于每个进程,我们在信号处理程序中捕获信号并将其推送到"未处理的信号堆栈"(USS)上,然后我们只需从信号处理程序例程返回即可。然后,我们的应用程序中有一些端点,特别是在IO操作之前和之后,然后处理USS中的所有信号。例如,如果 USS 中存在SIGUSR1,则每个进程将在终止点退出。
- 这个想法存在仍然存在死锁的问题,进程 1 只是捕获一个单数 befor 一个终止点,而进程 2 已经通过了这个点,现在正在启动并行 IO。 进程 1 将退出,这会导致进程 2 死锁(等待进程 1 退出的 IO)...
想法2:
只有主进程 0 捕获信号处理程序中的信号,然后发送广播消息:"所有进程退出! 在应用程序中的特定点。所有进程都接收广播和抛出以及异常,该异常在main
中捕获并调用MPI_FINALIZE
。
- 这样退出可以安全地发生,但代价是必须接收连续广播消息以查看我们是否应该退出
多谢!
如果您的目标是在同一点停止所有进程,那么就无法始终在可能的终止点同步。也就是说,需要在端点进行集体调用。
当然,你可以通过使用另一个集合调用的同步来避免额外的广播,以确保正确的终止,或者将终止信息打包在现有广播上,但我认为这不值得。毕竟,您只需要在 I/O 之前同步一次,并且至少每十分钟同步一次。在这样的频率下,即使是广播也不是性能问题。
在 MPI 应用程序中使用信号通常是不安全的。某些实现可能支持它,而其他实现可能不支持。
例如,在 MPICH 中,进程管理器使用 SIGUSR1
进行异常故障的内部通知。
http://lists.mpich.org/pipermail/discuss/2014-October/003242.html
另一方面,打开的 MPI 会将SIGUSR1
和SIGUSR2
从mpiexec
转发到其他进程。
http://www.open-mpi.org/doc/v1.6/man1/mpirun.1.php#sect14
其他实现会有所不同。因此,在你走得太远之前,请确保你使用的实现可以处理它。
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 创建LinkedList退出,返回代码为-11(SIGSEGV)
- 当我在main中声明了我的2d数组时,为什么我的程序会退出
- 如何让LLDB在成功时退出,在失败时等待
- C++控制台应用程序阻止退出
- 程序在执行程序的其余部分之前退出
- 构造函数在退出函数时无法初始化一个参数
- 为什么异常不退出程序?
- 我不断收到 [错误] ID 返回 1 退出状态错误,但看不到问题所在
- 退出简单while循环时出现问题
- 使用vscode调试时,GDB意外退出
- pclose() 不会给我进程退出代码
- 为什么系统函数总是在C++中返回已转移的退出状态?
- C++从另一个函数退出函数
- C++ 中的编译错误:未定义对"主"的引用 collect2:错误:ld 返回 1 个退出状态
- C++逗号分隔的输入数组代码过早退出
- Netbeans 10:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)
- 为什么 C++ 中的以下结构声明会导致退出 127?
- 编译问题:在函数"_start"中:未定义对"主"的引用 collect2:错误:ld 返回 1 个退出状态
- 进程退出,返回值3221226356写入系统( "cls" )。(已解决)