Как я могу разместить другие обработчики сигналов при захвате сигнала?

81
9

В Jesse Storimer отличная книга Работа с Unix-процессами, он рекомендует этот метод для захвата сигналов при размещении предыдущих обработчиков:


old_handler = trap(:QUIT) {
  # do some cleanup
  puts 'All done!'

  old_handler.call if old_handler.respond_to?(:call)
}


Это никогда не выходит из себя. Предположительно, если предыдущий обработчик вызывает exit, это прекрасно. Но что, если нет другого обработчика сигнала, только по умолчанию? Мои тесты показывают, что это означает, что процесс никогда не выйдет, потому что по умолчанию он не указан trap (old_handler будет строкой "DEFAULT").


Из предыдущего примера в книге, демонстрируя что-то еще:


old_handler = trap(:INT) {
  old_handler.call
  puts 'This is the second handler'
  exit
}

Итак, если old_handler вызывает exit, программа выйдет, и нам никогда не понадобится. Но если это не так, мы позаботимся о exit. Это кажется прекрасным. Немного странно, что все обработчики везде должны быть ответственны за то, что, возможно, это тот, который в конечном итоге закончит программу, зная, что только один из них будет.


В любом случае, если предположить, что это правда, вот что я нашел в качестве шаблона, который можно использовать повсеместно:


old_handler = trap("INT") do
puts "doing something custom in response to INT"
if old_handler.respond_to?(:call)
puts "calling old handler for INT"
old_handler.call
exit # in case old_handler is a bad citizen
else
case old_handler
when "DEFAULT"
puts "done with custom handlers, exiting in response to INT"
exit
when "IGNORE"
puts "done with custom handlers for INT, system default ignores it"
else
# in the case of EXIT it is nil. Not sure of other possibilities
puts "old_handler is : #{old_handler.class}"
end
end
end

Это правильный путь? Что-нибудь мне не хватает?

спросил(а) 2018-03-20T23:34:00+03:00 2 года, 7 месяцев назад
0
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема