Путаница при обработке сигналов SIGTERM

Я запускаю программу, которая вызывает сценарий оболочки (для обсуждения sh1 с pid 100). Этот сценарий, в свою очередь, вызывает другой сценарий (для обсуждения sh2 с pid 101) и ожидает его завершения. sh2 (дочерний скрипт) занимает около 50 секунд.

То, как я вызываю sh2 (/bin/sh2.sh)

Во время ожидания завершения дочернего процесса я пытаюсь завершить sh1 (используя kill -15 100). У меня есть функция обработчика в sh1 для обработки этого сигнала. Однако я замечаю, что мой sh1 (родительский скрипт) не завершается до тех пор, пока дочерний процесс не завершит свою работу (в течение 50 секунд), и только после этого этот сигнал обрабатывается.

Я изменил свой дочерний скрипт, чтобы он завершился за 30 секунд, и я заметил, что после выдачи SIGTERM на sh1 для завершения требуется около 30 секунд.

Это поведение при обработке SIGTERM? то есть оставаться заблокированным дочерним процессом? и только потом обрабатывать сигнал. Разве процесс не прерывается для обработки сигнала?

SIGNAL Обработка в родительском скрипте.

function clean_up()
{   
  //Do the cleanup
}

trap "clean_up $$; exit 0" TERM

person sdn_world    schedule 21.10.2015    source источник
comment
Что делает sh2, когда вы сигнализируете родителю?   -  person Etan Reisner    schedule 21.10.2015
comment
sh2 обрабатывает некоторую информацию и записывает ее в файл   -  person sdn_world    schedule 21.10.2015


Ответы (1)


Если sh1 вызывает sh2 и ждет его завершения, то он не запускает ловушку для сигнала до тех пор, пока не завершится sh2. То есть, если это sh1:

#!/bin/sh  
trap 'echo caught signal delayed' SIGTERM
sh2

затем sh1 поймает сигнал и ничего не сделает, пока sh2 не закончит работу, а затем выполнит ловушку. Если вы хотите, чтобы ловушка срабатывала сразу после отправки сигнала, вы можете запустить sh2 асинхронно и явно дождаться его:

#!/bin/sh
trap 'echo caught signal' SIGTERM
sh2&
wait

К сожалению, это не входит в ожидание. Если вам нужно продолжать ждать, на самом деле это невозможно сделать надежно, но вы можете приблизиться к этому:

#!/bin/sh
trap 'echo caught signal' SIGTERM
sh2&
(exit 129)   # prime the loop (eg, set $?) to simulate do/while
while test $? -gt 128; do wait; done

Это ненадежно, потому что вы не можете определить разницу между перехватом сигнала самостоятельно и завершением sh2 сигналом. Если вам нужно, чтобы это было надежно, вы должны переписать sh1 на языке, который позволяет лучше контролировать сигналы.

person William Pursell    schedule 21.10.2015