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

3
我在Windows上有一个Perl程序,需要在退出时执行清理操作。我使用了`sigtrap`编写了一个信号处理程序,但它并不总是有效。我可以拦截Ctrl-C,但如果机器重新启动或以其他方式终止程序,则既不运行信号处理程序也不运行END块。我读到Windows实际上没有信号,在Perl中,Windows的信号处理有点像黑客。我的问题是,如何以Windows方式处理异常终止?我想运行我的清理代码,无论程序如何或为什么终止(除了无法捕获的事件)。我读到Windows使用事件而不是信号,但我找不到有关如何在Perl中处理Windows事件的信息。
不幸的是,我没有安装来自CPAN的模块的权限,所以我必须使用原始的ActiveState Perl。更有趣的是,我使用的大多数机器只有Perl 5.6.1。
编辑:我将感激任何答案,即使它们需要CPAN模块或更新版本的Perl。我想了解Perl中的Windows事件处理,欢迎提供任何信息。

1
Perl 5.6.1是什么,像是10年前的东西?你的机器上装的是Win98/2000/ME吗?=) - TLP
我们所有的台式机都使用Windows XP。希望在微软停止支持XP之前,我们能升级到Windows 7。信不信由你,我们有一些机器仍在使用IE6,因为我们的一些内部应用程序只能在IE6上运行。 - Jonathan
2
我的意思是作为一个参考.. Perl 5.6.1 已经和那些操作系统一样古老了。这总让我想知道为什么人们不更新 Perl。这并不像不更新其他软件一样是个好主意。 - TLP
1个回答

3
在所有操作系统中,您都可以突然终止任何程序。想想Unix / Linux中的kill -9命令。您可以在任何程序上执行此操作,它会立即停止。无法陷入其中。程序无法请求更多的操作系统周期以进行清理。
我不了解Unix和Windows信号之间的区别,但您可以想象为什么每个操作系统都必须允许我们在Unix中所谓的SIGKILL - 一种确保和立即杀死任何程序的方法。
想象一下,您有一个有错误的程序拦截了终止请求(在Unix中是SIGTERM),并进入清理阶段。该程序没有进行清理,而是陷入了一个循环中,请求越来越多的内存。如果您不能拉动紧急绳索,则会被卡住。
当然,最终的是墙上的插头。拔下它,程序(以及其他所有内容)就会突然停止。没有办法让您的程序说:“嗯...电源断了,机器停止运行了...最好启动旧的清理程序!”
因此,您无法捕获每个程序终止信号,您的程序将不得不考虑到这一点。您可以做的是查看您的程序是否需要在运行之前进行清理。在Windows上,您可以在程序启动时在注册表中放置一个条目,并在关闭并进行清理时将其删除。在Unix中,您可以在$ENV{HOME}目录中放置以点开头的文件或目录名称。
回到1980年代,我为一种非常专有的操作系统编写了会计软件。当用户按下ESC键时,我们应该立即返回主菜单。如果用户正在输入订单并从库存中取出物品,则交易将不完整,并且库存将显示物品已被售出,即使订单不完整也是如此。解决方案是在下次有人输入订单时检查这些不完整的订单,并在输入新订单之前撤消库存更改。您的程序可能需要执行类似的操作。

我理解您的意思,但那不是我想问的。在我的原始问题中,我说“不包括无法捕获的事件”。我知道我无法捕获Windows等效的SIGKILL或其他即时致命错误,但我希望能够捕获相当于SIGTERM和类似信号。但由于某种原因,我的信号处理程序除了Ctrl-C之外没有被调用。我想学习如何直接使用Windows事件,而不是通过不完整的Unix信号仿真。 - Jonathan
1
@Jonathan - 对于之前的混淆表示抱歉。Perl在Cntrl-C上模拟SIGTERM,但除此之外,Windows不使用可以捕获的信号。你可以查看Win32::Events,它与Windows事件处理相关联。这是Windows在某种程度上使用的替代信号的方式。 - David W.
Win32::Events的参考资料很有用,但是文档只讲解如何创建和操作事件。当进程被终止时生成的任何事件都需要被捕获。你能指导我去哪里找到相关信息吗?我已经在Google上搜过"catch windows events in perl",但几乎找不到什么信息。 - Jonathan
@Jonathan - 我不是Windows程序员。据我所知,通用的Win32 _signals_非常少。Win32使用事件,客户端和服务器需要创建一组它们用于通信的_事件_。有一些预定义的系统范围事件,例如CTRL_C_EVENTCTRL_BREAK_EVENTCTRL_CLOSE_EVENTCTRL_LOGOFF_EVENTCTRL_SHUTDOWN_EVENT。您可以尝试使用Win32::Events捕获这些事件。 - David W.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接