Очевидно, mpirun
использует обработчик SIGINT, который «пересылает» сигнал SIGINT каждому из порожденных им процессов.
Это означает, что вы можете написать обработчик прерывания для своего кода с поддержкой mpi, выполнить mpirun -np 3 my-mpi-enabled-executable
, а затем SIGINT будет вызываться для каждого из трех процессов. Вскоре после этого mpirun завершает работу. Это отлично работает, когда у вас есть небольшой пользовательский обработчик, который только печатает сообщение об ошибке, а затем завершает работу. Однако, когда ваш пользовательский обработчик прерывания выполняет нетривиальную работу (например, выполняет серьезные вычисления или сохраняет данные), обработчик не выполняется до завершения. Я предполагаю, что это связано с тем, что mpirun решил выйти слишком рано.
Вот stderr при нажатии ctrl-c
(т.е. вызов SIGINT) после выполнения my-mpi-enabled-executable
. Это желаемое ожидаемое поведение:
interrupted by signal 2.
running viterbi... done.
persisting parameters... done.
the master process will now exit.
Вот stderr при нажатии ctrl-c
после выполнения mpirun -np 1 my-mpi-enabled-executable
. Это проблемное поведение:
interrupted by signal 2.
running viterbi... mpirun: killing job...
--------------------------------------------------------------------------
mpirun noticed that process rank 0 with PID 8970 on node pharaoh exited on signal 0 (Unknown signal 0).
--------------------------------------------------------------------------
mpirun: clean termination accomplished
Ответ на любой из следующих вопросов решит мою проблему:
- Как переопределить обработчик mpirun SIGINT (если это вообще возможно)?
- Как избежать завершения процессов, созданных mpirun сразу после завершения работы mpirun?
- Есть ли другой сигнал, который mpirun может отправлять дочерним процессам до завершения mpirun?
- Есть ли способ «захватить» так называемый «сигнал 0 (Неизвестный сигнал 0)» (см. Второй stderr выше)?
Я использую openmpi-1.6.3 на Linux.