【问题标题】:perl: executing multiple systems processes and waiting for them to finishperl:执行多个系统进程并等待它们完成
【发布时间】:2012-03-04 11:06:51
【问题描述】:

目前在我的 Perl 脚本中,我进行如下调用:

system(" ./long_program1 & ./long_program2 & ./long_program3 & wait ");

我希望能够记录每个长时间运行的命令何时执行,同时仍然异步执行它们。我知道系统调用会导致 perl 进行分叉,那么这样的事情可能吗?这可以用多个 perl fork() 和 exec() 调用代替吗?

请帮我找到更好的解决方案。

【问题讨论】:

  • 您要记录结束时间还是只记录开始时间?进程启动时要记录哪些信息,进程退出时要记录哪些信息?

标签: perl bash logging fork


【解决方案1】:

是的,当然。您可以为每个要执行的程序派生一个子进程。

您可以在 fork 之后执行 system()exec(),具体取决于您希望 Perl 代码在系统调用完成后执行多少处理(因为 exec() 在功能上与 system(); exit $rc; 非常相似)

foreach my $i (1, 2, 3) {
    my $pid = fork();
    if ($pid==0) { # child
        exec("./long_program$i");
        die "Exec $i failed: $!\n";
    } elsif (!defined $pid) {
        warn "Fork $i failed: $!\n";
    }
}

1 while wait() >= 0;

请注意,如果您需要进行大量分叉,最好通过Parallel::ForkManager 控制它们,而不是手动进行分叉。

【讨论】:

  • exec 在很多方面都不等同于 systemexit。 (其实system使用exec。)
  • @ikegami - 是的,我过于简单化了,因为它与主要 Q 不太相关。我会重新措辞
【解决方案2】:

两种选择:


use IPC::Open3 qw( open3 );

sub launch {
   open(local *CHILD_STDIN, '<', '/dev/null') or die $!;
   return open3('<&CHILD_STDIN', '>&STDOUT', '>&STDERR', @_);
}

my %children;
for my $cmd (@cmds) {
   print "Command $cmd started at ".localtime."\n";
   my $pid = launch($cmd);
   $children{$pid} = $cmd;
}

while (%children) {
   my $pid = wait();
   die $! if $pid < 1;
   my $cmd = delete($children{$pid});
   print "Command $cmd ended at ".localtime." with \$? = $?."\n";
}

我使用open3,因为它比一个简单的fork+exec 更短,而且它不会将exec 错误归因于你启动的命令,就像一个简单的fork+exec


use threads;

my @threads;
for my $cmd (@cmds) {
   push @threads, async {
      print "Command $cmd started at ".localtime."\n";
      system($cmd);
      print "Command $cmd ended at ".localtime." with \$? = $?."\n";
   };
}

$_->join() for @threads;

【讨论】:

  • 在这种情况下使用多线程而不是多进程有什么好处?
  • @Blaskovicz,它不使用线程而不是进程。它启动完全相同的过程。至于第二个 sn-p 中的代码相对于第一个 sn-p 中的代码的优势,应该是显而易见的:简单。
  • 使用选项的线程很漂亮,很干净,而且效果很好!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-21
  • 2016-09-09
  • 2019-02-23
  • 1970-01-01
  • 1970-01-01
  • 2019-03-24
  • 2021-10-29
相关资源
最近更新 更多