gpt4 book ai didi

perl - 如何并行运行 perl 脚本并捕获文件中的输出?

转载 作者:行者123 更新时间:2023-12-02 18:32:08 25 4
gpt4 key购买 nike

我需要并行运行 Perl 测试,并为每个测试文件在单独的文件中捕获 STDOUT 和 STDERR。即使在一个文件中捕获,我也没有成功。我一直都这样,但没有运气。这就是我开始的地方(我不会给你带来所有的变化)。任何帮助是极大的赞赏。谢谢!

foreach my $file ( @files) {
next unless $file =~ /\.t$/;
print "\$file = $file\n";

$file =~ /^(\w+)\.\w+/;

my $file_pfx = $1;
my $this_test_file_name = $file_pfx . '.txt';

system("perl $test_dir\\$file > results\\$test_file_name.txt &") && die "cmd failed: $!\n";

}

最佳答案

这是一个使用 Parallel::ForkManager 的简单示例产生单独的进程。

在每个进程中,STDOUTSTDERR 流都被重定向,对于演示,有两种方式:STDOUT 到变量,然后可以根据需要传递(此处转储到文件中),并将 STDERR 直接传递到文件。或者使用库,并在单独的代码片段中提供示例。

数字1..6代表每个 child 将选择处理的数据批处理。仅立即启动三个进程,然后当一个进程完成时,另一个进程将在其位置启动。(在这里,它们几乎立即退出,“作业”微不足道。)

use warnings;
use strict;
use feature 'say';

use Carp qw(carp)
use Path::Tiny qw(path);
use Parallel::ForkManager;

my $pm = Parallel::ForkManager->new(3);

foreach my $data (1..6) {
$pm->start and next; # start a child process
proc_in_child($data); # code that runs in the child process
$pm->finish; # exit it
}
$pm->wait_all_children; # reap all child processes

say "\nParent $$ done\n";

sub proc_in_child {
my ($data) = @_;
say "Process $$ with data $data"; # still shows on terminal

# Will dump all that was printed to streams to these files
my (outfile, $errfile) =
map { "proc_data-${data}_" . $_ . ".$$.out" } qw(stdout stderr);

# Redirect streams
# One way to do it, redirect to a variable (for STDOUT)...
open my $fh_stdout, ">", \my $so or carp "Can't open handle to variable: $!";
my $fh_STDOUT = select $fh_stdout;
# ...another way to do it, directly to a file (for any stream)
# (first 'dup' it so it can be restored if needed)
open my $SAVEERR, ">&STDERR" or carp "Can't dup STDERR: $!";
open *STDERR, ">", $errfile or carp "Can't redirect STDERR to $errfile: $!";

# Prints wind up in a variable (for STDOUT) and a file (for STDERR)
say "STDOUT: Child process with pid $$, processing data #$data";
warn "STDERR: Child process with pid $$, processing data #$data";

close $fh_stdout;
# If needed to restore (not in this example which exits right away)
select $fh_STDOUT;
open STDERR, '>&', $SAVEERR or carp "Can't reopen STDERR: $!";

# Dump all collected STDOUT to a file (or pass it around, it's a variable)
path( $outfile )->spew($so);

return 1
}

虽然STDOUT被重定向到变量,但STDERR不能以这种方式重定向,这里它直接转到文件。请参阅open 。不过,也有一些方法可以将其捕获到变量中。

然后您可以使用模块从子进程返回到父进程的功能,然后父进程可以处理这些变量。例如,参见this postthis postthis post 。 (还有更多,这些只是我所知道的。)或者实际上只是将它们转储到文件中,就像这里所做的那样。

另一种方法是使用可以运行代码和重定向输出的模块,例如 Capture::Tiny

use Capture::Tiny qw(capture);

sub proc_in_child {
my ($data) = @_;
say "Process $$ with data $data"; # on terminal

# Run code and capture all output
my ($stdout, $stderr, @results) = capture {
say "STDOUT: Child process $$, processing data #$data";
warn "STDERR: Child process $$, processing data #$data";

# return results perhaps...
1 .. 4;
}

# Do as needed with variables with collected STDOUT and STDERR
# Return to parent, or dump to file:
my ($outfile, $errfile) =
map { "proc_data-${data}_" . $_ . ".$$.out" } qw(stdout stderr);

path($outfile) -> spew( $stdout );
path($errfile) -> spew( $stderr );

return 1
}

这会保持相同数量的进程运行。或者,可以将其设置为等待整批完成,然后开始另一批。一些操作细节参见this post

关于perl - 如何并行运行 perl 脚本并捕获文件中的输出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69286787/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com