Как обработать ненормальное завершение программы в Perl на Windows - PullRequest
3 голосов
/ 05 декабря 2011

У меня есть программа на Perl в Windows, которая должна выполнить действия по очистке при выходе. Я написал обработчик сигнала, используя sigtrap, но он не всегда работает. Я могу перехватить Ctrl-C, но если машина перезагружается или программа уничтожается другим способом, ни обработчик сигнала, ни блок END не запускаются. Я читал, что в Windows на самом деле нет сигналов, и обработка сигналов в Windows - это своего рода взлом в Perl. У меня вопрос, как я могу справиться с ненормальным завершением пути Windows? Я хочу запустить мой код очистки независимо от того, как или почему программа завершается (исключая события, которые не могут быть перехвачены) Я читал, что Windows использует события вместо сигналов, но я не могу найти информацию о том, как обращаться с событиями Windows в Perl.

К сожалению, у меня нет полномочий для установки модулей из CPAN, поэтому мне придется использовать ванильный ActiveState Perl. И что еще интереснее, большинство машин, которые я использую, имеют только Perl 5.6.1.

Редактировать: Буду признателен за любые ответы, даже если для них требуются модули CPAN или более новые версии Perl. Я хочу узнать об обработке событий Windows в Perl, и любая информация будет приветствоваться.

1 Ответ

3 голосов
/ 05 декабря 2011

Во всех операционных системах вы всегда можете внезапно завершить любую программу.Подумайте о команде kill -9 в Unix / Linux.Вы делаете это в любой программе, и она мгновенно останавливается.Нет способа поймать его в ловушку.У программы нет возможности запросить еще несколько циклов операционной системы для очистки.

Я не в курсе разницы между сигналами Unix и Windows, но вы можете представить, почему каждая ОС должна разрешать то, что мы называемв Unix SIGKILL - верный и немедленный способ уничтожения любой программы.

Представьте, что у вас есть программа с ошибками, которая перехватывает запрос на завершение (SIGTERM в Unix) и вводит очисткуфаза.Вместо очистки программа застревает в цикле, который запрашивает все больше и больше памяти.Если бы вы не смогли вытащить аварийный шнур SIGKILL , вы застряли бы.

Окончательный SIGKILL , конечно, это вилка в стене.Потяните его, и программа (вместе со всем остальным) замирает.Ваша программа никак не может сказать: " Хм ... питание отключено, и машины перестали работать ... Лучше запустите старую процедуру очистки! "

Так что неттаким образом, вы можете перехватывать каждый сигнал завершения программы, и ваша программа должна будет учитывать это.Что вы можете сделать, это посмотреть, нужно ли вашей программе выполнить очистку перед запуском.В Windows вы можете поместить запись в реестр при запуске программы и удалить ее, когда она выключается и выполняет очистку.В Unix вы можете поместить имя файла или каталога, начиная с точки, в каталог $ENV{HOME}.

Еще в 1980-х годах я писал бухгалтерское программное обеспечение для очень проприетарной ОС.Когда пользователь нажал кнопку ESCAPE, мы должны были немедленно вернуться в главное меню.Если пользователь вводил заказ и брал вещи из инвентаря, транзакция была бы незавершенной, и инвентарь показывал бы товары как продано , даже если заказ был неполным.Решение состояло в том, чтобы проверить эти незавершенные заказы в следующий раз, когда кто-то ввел заказ, и откатить изменения в инвентаре до ввода нового заказа.Ваша программа может делать что-то подобное.

...