BEGIN {
while (1) {
print "hi\n";
}
}
END {
print "end is called\n";
}
shell中的:
kill <pid>
输出:
hi
hi
hi
hi
hi
hi
hi
hi
hi
Terminated
当我通过kill或ctrl-c杀死它时,没有调用结束块。
在程序退出之前是否总会调用等效的东西
答案 0 :(得分:4)
Ctrl C向您的程序发送SIGINT
。你可以抓住&#39;通过在%SIG
中设置适当的条目,使用信号处理程序。我会注意到 - 我不明白为什么你这样使用BEGIN
。 BEGIN
是一个特殊的代码块,在编译时调用 - 在第一次机会。这意味着当您运行perl -c
来验证代码时会触发它,因此设置为无限循环确实是一个坏主意。请参阅:perlmod
E.g。
#!/usr/bin/perl
use strict;
use warnings;
$SIG{'INT'} = \&handle_kill;
my $finished = 0;
sub handle_kill {
print "Caught a kill signal\n";
$finished++;
}
while ( not $finished ) {
print "Not finished yet\n";
sleep 1;
}
END {
print "end is called\n";
}
但是有一个缺点 - 有些信号你不能以这种方式陷阱。有关详细信息,请参阅perlipc
。
某些信号既不会被捕获也不会被忽略,例如KILL和STOP(但不是TSTP)信号。请注意,忽略信号会使它们消失。如果你只想暂时阻止它们而不让它们迷路,你就必须使用POSIX&#39; sigprocmask。
默认情况下,如果您发送kill
,则会发送SIGTERM
。所以你可能也想要覆盖这个处理程序。然而,除了使用SIGTERM优雅地退出之外,做任何其他事情通常都被认为是不好的事情 - 做某事&#39;更容易接受。捕获SIGHUP
(挂断)和SIGINT
时恢复。
你应该注意到Perl会发出安全信号&#39;虽然 - 所以一些系统调用不会被中断,perl会在处理信号之前等待它返回。这是因为如果您中止某些操作(例如close
在您正在刷新数据的文件上可能会导致其损坏),则可能会发生错误的事情。通常这不是问题,但需要注意的事项。
答案 1 :(得分:3)
在你的代码中输入正确的信号处理程序:
$SIG{INT} = sub { die "Caught a sigint $!" };
control-c将SIGINT信号发送给脚本,该脚本由此处理程序
捕获