【问题标题】:Implementation of a watchdog in perlperl中看门狗的实现
【发布时间】:2014-02-03 14:52:17
【问题描述】:

我需要将外部进程(命令行调用)的执行包含在固定的时间窗口中。

经过几次阅读后,我编写了这个实现:

#/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 &gt; $sleepTime 返回时:

From ml: Good morning
From main: Good morning

另一方面,当$timeout &lt; $sleepTime

From watchdog: timeout!

获得的行为是正确的,但我认为这种方法有点原始。

我想知道是否有库可以帮助改进源代码以提高可读性和性能。有什么建议吗?

【问题讨论】:

    标签: multithreading perl shell process watchdog


    【解决方案1】:

    IPC::Run 允许您运行子进程并与它们的stdinstdoutstderr 交互。也可以设置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
    }
    

    注意有一些limitations when running on Windows

    【讨论】:

      【解决方案2】:

      您可以从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 秒后被杀死。

      【讨论】:

      • 好的。在这种方法中,我想,将 stdout 和 stderr 流 重定向到 perl 数组的唯一方法是通过 shell 输出重定向运算符并填充文本文件。然后从中读取行。还是我错了?我的意思是,还是有更好的方法?
      • @FilippoLauria 还有其他方法。例如,Capture::Tiny: use Capture::Tiny qw(capture); use Proc::Background qw(timeout_system); my ($stdout, $stderr, $exit) = capture { timeout_system($seconds, $command); }; 不确定这是最好的方式,但它是一种选择。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多