我需要在固定的时间窗口中包含外部进程(命令行调用)的执行。
经过几次阅读后,我编写了这个实现:
#/bin/perl -w
use IPC::System::Simple qw( capture );
use strict;
use threads;
use threads::shared;
use warnings;
my $timeout = 4;
share($timeout);
my $stdout;
share($stdout);
my $can_proceed = 1;
share($can_proceed);
sub watchdogFork {
my $time1 = time;
my $ml = async {
my $sleepTime = 2;
my $thr = threads->self();
$stdout = capture("sleep $sleepTime; echo \"Good morning\n\";");
print "From ml: " . $stdout;
$thr->detach();
};
my $time2;
do {
$time2 = time - $time1;
} while ( $time2 < $timeout );
print "\n";
if ( $ml->is_running() ) {
print "From watchdog: timeout!\n";
$can_proceed = 0;
$ml->detach();
}
}
my $wd = threads->create('watchdogFork');
$wd->join();
print "From main: " . $stdout if ($can_proceed);
当$timeout > $sleepTime
返回时:
From ml: Good morning
From main: Good morning
另一方面,当$timeout < $sleepTime
:
From watchdog: timeout!
获得的行为是正确的,但我认为这种做法略显原始。
我想知道是否有库可以帮助改进源代码以提高可读性和性能。有什么建议吗?
答案 0 :(得分:2)
IPC::Run可让您运行子流程并与其stdin
,stdout
和stderr
进行互动。您还可以设置timeouts,在超出时抛出异常:
use IPC::Run qw(harness run timeout);
my @cmd = qw(sleep 10);
my $harness = harness \@cmd, \undef, \my $out, \my $err, timeout(3);
eval {
run $harness or die "sleep: $?";
};
if ($@) {
my $exception = $@; # Preserve $@ in case another exception occurs
$harness->kill_kill;
print $exception; # and continue with the rest of the program
}
答案 1 :(得分:1)
您可以使用Proc::Background中的timeout_system
:
use Proc::Background qw(timeout_system);
my $wait_status = timeout_system($seconds, $command, $arg1, $arg2);
my $exit_code = $wait_status >> 8;
该过程将在$seconds
秒后被杀死。