【发布时间】:2011-04-27 10:01:45
【问题描述】:
有时我的系统调用会进入永无止境的状态。为了避免我希望能够在指定的时间后中断通话。
有没有办法为system指定超时限制?
system("command", "arg1", "arg2", "arg3");
我希望从 Perl 代码中实现超时以实现可移植性,而不是使用某些特定于操作系统的函数,例如 ulimit。
【问题讨论】:
有时我的系统调用会进入永无止境的状态。为了避免我希望能够在指定的时间后中断通话。
有没有办法为system指定超时限制?
system("command", "arg1", "arg2", "arg3");
我希望从 Perl 代码中实现超时以实现可移植性,而不是使用某些特定于操作系统的函数,例如 ulimit。
【问题讨论】:
请参阅alarm 函数。来自 pod 的示例:
eval {
local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
alarm $timeout;
$nread = sysread SOCKET, $buffer, $size;
alarm 0;
};
if ($@) {
die unless $@ eq "alarm\n"; # propagate unexpected errors
# timed out
}
else {
# didn't
}
CPAN 上有一些模块可以更好地包装这些模块,例如:Time::Out
use Time::Out qw(timeout) ;
timeout $nb_secs => sub {
# your code goes were and will be interrupted if it runs
# for more than $nb_secs seconds.
};
if ($@){
# operation timed-out
}
你可以使用IPC::Run的run方法代替system。并设置超时。
【讨论】:
System::Timeout 怎么样?
此模块扩展
system以允许在指定秒数后超时。
timeout("3", "sleep 9"); # timeout exit after 3 seconds
【讨论】:
我之前在 Perl + Linux 中使用过timeout 命令,你可以这样测试:
for(0..4){
my $command="sleep $_"; #your command
print "$command, ";
system("timeout 1.1s $command"); # kill after 1.1 seconds
if ($? == -1 ){ printf "failed to execute: $!" }
elsif($?&127 ){ printf "died, signal %d, %scoredump", $?&127, $?&128?'':'no '}
elsif($?>>8==124){ printf "timed out" }
else { printf "child finished, exit value %d", $? >> 8 }
print "\n";
}
4.317 秒后的输出:
sleep 0, child finished, exit value 0
sleep 1, child finished, exit value 0
sleep 2, timed out
sleep 3, timed out
sleep 4, timed out
timeout 命令是所有主要“正常”Linux 发行版 a.f.a.i.k 的一部分,也是 coreutils 的一部分。
【讨论】: