为什么这个简单的脚本:
#! 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";
)做同样的事情,窗口会关闭,但无论如何都不会执行干净的退出)(好吧,我承认在Debian 6.0.4的Windows 7 amd64 -vs- perl 5, version 14, subversion 2 (v5.14.2) built for MSWin32-x86-multi-thread
上是草莓perl, v5.10.1 (*) built for x86_64-linux-gnu-thread-multi
,但我怀疑这些基本内容是否重要。编辑:我刚用类似的方法在ActiveState perl 5.12上检查它,它是相同的,所以显然这个问题并不是草莓所隔离的。)
我知道perlport说得很清楚,
不要指望任何信号或%SIG。
但必须有办法...(另外,我想了解。)
那么应该做些什么呢?
答案 0 :(得分:4)
您可以使用sigtrap
pragma:
use sigtrap 'handler', \&cleanup, 'normal-signals';
当捕获到信号时,这将调用方法cleanup
并将信号识别作为参数传递。
答案 1 :(得分:1)
在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窗口的关闭时似乎没有传递该事件< / p>
答案 2 :(得分:1)
在添加了更多print
之后,我发现实际上代码 可以正常工作,除了它在sleep
期间不会中断。
因此,只需将sleep 60
更改为更“现实”sleep 1 foreach (1..10);
,就会带来更多可接受的行为。
当然,它在Windows上的工作方式与在* nix上的工作方式不同。