perl:执行多个系统进程并等待它们完成

时间:2012-02-12 23:51:29

标签: perl bash logging fork

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

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

我希望能够在每个长时间运行的命令执行时记录,同时仍然执行它们异步。我知道系统调用导致perl生成一个fork,所以这样的事情可能吗?这可以被多个perl fork()和exec()调用替换吗?

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

2 个答案:

答案 0 :(得分:6)

是的,当然。您可以为每个要执行的程序分叉子进程。

您可以在分叉后执行system()exec(),具体取决于系统调用完成后您希望Perl代码执行多少处理(因为exec()在功能上与{非常相似} {1}})

system(); exit $rc;

请注意,如果您需要做很多分叉,最好通过Parallel::ForkManager控制它们,而不是手工分叉。

答案 1 :(得分:3)

两种选择:


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;