如何在Windows上处理Perl中的异常程序终止

时间:2011-12-05 13:51:02

标签: windows perl events signals activestate

我在Windows上有一个需要在退出时执行清理操作的Perl程序。我使用sigtrap编写了一个信号处理程序,但它并不总是有效。我可以拦截Ctrl-C,但是如果重新启动机器或者以其他方式杀死程序,则不会运行信号处理程序和END块。我已经读过Windows没有真正的信号,而且Windows上的信号处理在Perl中是一种破解。我的问题是,我如何处理Windows方式的异常终止?我想运行我的清理代码,无论程序如何或为何终止(不包括无法捕获的事件)。我已经读过Windows使用事件而不是信号,但我找不到有关如何处理Perl中的Windows事件的信息。

不幸的是,我没有权限从CPAN安装模块,因此我将不得不使用vanilla ActiveState Perl。为了让事情变得更有趣,我使用的大部分机器都只有Perl 5.6.1。

编辑:即使他们需要CPAN模块或更新版本的Perl,我将不胜感激。我想了解Perl中的Windows事件处理,欢迎任何信息。

1 个答案:

答案 0 :(得分:3)

在所有操作系统中,您始终可以突然终止任何程序。想想Unix / Linux中的kill -9命令。你可以在任何程序上执行此操作,并立即停止。没办法陷阱。程序无法请求更多操作系统周期进行清理。

我不知道Unix和Windows信号之间的区别,但是你可以想象为什么每个操作系统必须允许我们在Unix中使用的语言 SIGKILL - 这是一种可靠而直接的杀死任何程序的方法。

想象一下,您有一个错误的程序拦截终止请求(Unix中的SIGTERM),并进入清理阶段。而不是清理,程序而是陷入一个请求越来越多内存的循环中。如果您无法拉动 SIGKILL 紧急电源线,那么您将被卡住。

终极 SIGKILL 当然是插墙。拉它,程序(以及其他一切)戛然而止。你的程序无法说“嗯...电源已关闭且机器已停止运行......更好地启动旧的清理程序!

因此,您无法捕获每个程序终止信号,并且您的程序必须考虑到这一点。您可以做的是查看您的程序是否需要在运行之前进行清理。在Windows上,您可以在程序启动时在注册表中放入一个条目,并在它关闭并清理时将其删除。在Unix中,您可以在$ENV{HOME}目录中以句点开头放置文件或目录名称。

回到20世纪80年代,我为一个非常专有的操作系​​统编写了会计软件。当用户按下ESCAPE按钮时,我们假设立即返回主菜单。如果用户正在输入订单,并从库存中取出物品,则交易将不完整,并且库存将显示项目已售出,即使订单不完整。解决方案是在下次有人输入订单时检查这些未完成的订单,并在输入新订单之前退出库存中的更改。你的程序可能需要做类似的事情。

相关问题