使用mpirun
时,是否可以在正在运行的代码中捕获信号(例如,^C
生成的SIGINT)?
例如,我正在运行并行化的python代码。我可以except KeyboardInterrupt
在自己运行python blah.py
时捕获这些错误,但在执行mpirun -np 1 python blah.py
时我无法做到。
有人有建议吗?即使找到如何在C或C ++编译的程序中捕获信号也是一个有用的开始。
如果我向生成的Python进程发送信号,它们可以正确处理信号;但是,发送到父orterun
进程的信号(即从群集上超过挂起时间,或在终端中按下control-C)将立即终止所有内容。
答案 0 :(得分:2)
我认为这实际上取决于实现。
在SLURM中,我尝试使用sbatch --signal USR1@30
将SIGUSR1
(其签名为30,10或16)发送到srun
命令启动的程序。并且该过程收到信号SIGUSR1 = 10
。
对于IBM的平台MPI,根据https://www.ibm.com/support/knowledgecenter/en/SSF4ZA_9.1.4/pmpi_guide/signal_propagation.html
SIGINT, SIGUSR1, SIGUSR2
将被绕过进程。
在MPICH中,进程管理器使用SIGUSR1进行异常故障的内部通知。 参考:http://lists.mpich.org/pipermail/discuss/2014-October/003242.html>
另一方面打开MPI会将来自mpiexec的SIGUSR1和SIGUSR2转发给其他进程。 参考:http://www.open-mpi.org/doc/v1.6/man1/mpirun.1.php#sect14>
对于IntelMPI,根据https://software.intel.com/en-us/mpi-developer-reference-linux-hydra-environment-variables
I_MPI_JOB_SIGNAL_PROPAGATION
和I_MPI_JOB_TIMEOUT_SIGNAL
可以设置为发送信号。
另一件值得注意的事情是:对于许多python脚本,他们将通过cython调用其他库或代码,如果子进程捕获SIGUSR1
,可能会发生不需要的事情。
答案 1 :(得分:1)
如果您使用mpirun --nw
,那么mpirun
本身应该在启动子进程后立即终止,而不是等待终止;如果这是可以接受的,那么我相信你的过程能够捕获自己的信号。
答案 2 :(得分:-1)
signal模块支持使用signal.signal
设置信号处理程序:
将信号signalnum的处理程序设置为函数处理程序。 handler可以是一个可调用的Python对象,它带有两个参数(见下文),或者是一个特殊值signal.SIG_IGN或signal.SIG_DFL。将返回先前的信号处理程序......
import signal
def ignore(sig, stack):
print "I'm ignoring signal %d" % (sig, )
signal.signal(signal.SIGINT, ignore)
while True: pass
如果您将SIGINT
发送给运行此脚本的Python解释器(通过kill -INT <pid>
),它将打印一条消息并继续运行。