我在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事件处理,欢迎任何信息。
答案 0 :(得分:3)
在所有操作系统中,您始终可以突然终止任何程序。想想Unix / Linux中的kill -9
命令。你可以在任何程序上执行此操作,并立即停止。没办法陷阱。程序无法请求更多操作系统周期进行清理。
我不知道Unix和Windows信号之间的区别,但是你可以想象为什么每个操作系统必须允许我们在Unix中使用的语言 SIGKILL - 这是一种可靠而直接的杀死任何程序的方法。
想象一下,您有一个错误的程序拦截终止请求(Unix中的SIGTERM),并进入清理阶段。而不是清理,程序而是陷入一个请求越来越多内存的循环中。如果您无法拉动 SIGKILL 紧急电源线,那么您将被卡住。
终极 SIGKILL 当然是插墙。拉它,程序(以及其他一切)戛然而止。你的程序无法说“嗯...电源已关闭且机器已停止运行......更好地启动旧的清理程序!”
因此,您无法捕获每个程序终止信号,并且您的程序必须考虑到这一点。您可以做的是查看您的程序是否需要在运行之前进行清理。在Windows上,您可以在程序启动时在注册表中放入一个条目,并在它关闭并清理时将其删除。在Unix中,您可以在$ENV{HOME}
目录中以句点开头放置文件或目录名称。