为何这个简单的脚本:
#! perl -w use strict; use warnings; $| = 1; my $LOCKFILE = "$0.lock"; sub mklock { open my $lf, ">", $LOCKFILE; print $lf $$; close $lf; } sub rmlock { unlink $LOCKFILE; } sub clean_exit { rmlock; exit 0; } sub work { print "working..."; sleep 10; # although `sleep 1 foreach (1..10);` # *does* interrupt---between `sleep`s--see my answer print "done.\n" } $SIG{INT} = "clean_exit"; mklock; work; rmlock;
在Debian上运行,但不在Windows上运行?
$SIG{INT} = \&clean_exit;
,行为似乎是一样的 SIGHUP
( $SIG{HUP} = "clean_exit";
)做同样的操作,窗口closures,但干净的退出不会执行) (好吧,我承认,它是perl 5, version 14, subversion 2 (v5.14.2) built for MSWin32-x86-multi-thread
Windows 7上的perl 5, version 14, subversion 2 (v5.14.2) built for MSWin32-x86-multi-thread
的草莓perl 5, version 14, subversion 2 (v5.14.2) built for MSWin32-x86-multi-thread
amd64 -vs- perl, v5.10.1 (*) built for x86_64-linux-gnu-thread-multi
在Debian 6.0.4框中,但我怀疑这是基本的东西。 编辑:我刚刚检查过与ActiveState的perl 5.12类似的盒子,这是相同的,显然这个问题不是孤立的草莓。)
我知道perlport说清楚,
不要指望任何信号或%SIG。
但一定有办法…(另外,我想明白)
那么应该做些什么不同?
您可以使用sigtrap
注:
use sigtrap 'handler', \&cleanup, 'normal-signals';
当信号被捕获时,这将调用方法cleanup
,并将信号标识作为参数传递。
在添加了更多的print
之后,我发现实际上,代码确实起作用,除了在sleep
期间不中断。
所以只是改变sleep 60
更“现实”的sleep 1 foreach (1..10);
带来更多可接受的行为。
当然,它在Windows上的工作方式与在* nix上的工作方式不同。
遵循DOS应用程序中的unix行纪律是一种奢侈,而不是一种权利。
它遵守Ctrl+Break
,这是Ctrl + C的等效窗口
编辑改变为Ctrl + Break – 这是我得到使用Mac键盘。
为了测试中断处理的目的,你应该在你的工作副本中使用下面的循环,否则在触发处理程序之前一直等到整个睡眠完成。
sub work { print "working..."; my $i = 0; while ($i < 10) { sleep(1); $i--; } say "done." }
这样就更容易检测到按键 – 正在进行睡眠时中断处理没有被检测到。
让我感到困惑 – INT处理程序正在工作!
编辑 Perl的原始源代码声称它应该支持HUP作为关闭窗口事件,但是当我点击一个CMD窗口关闭时,事件似乎没有被传递