我想在我的脚本中处理子任务中的文件列表,并且我使用Proc::Async
来生成执行该工作的子进程。缺点是,如果我要处理大量文件,它将产生许多子进程。我想知道如何限制Proc::Async
产生的并发子进程数?
答案 0 :(得分:4)
您可以使用Jonathan Worthington在his concurrency/parallelism/asynchrony talk at the 2019 German Perl Workshop中演示的这种反应块技术明确限制Proc::Async
进程的数量(例如,参见幻灯片39)。我使用Linux命令echo N
作为我的"外部进程"在下面的代码中。
#!/bin/env perl6
my @items = <foo bar baz>;
for @items -> $item {
start { say "Planning on processing $item" }
}
# Run 2 processes at a time
my $degree = 2;
react {
# Start $degree processes at first
run-one-process for 1..$degree;
# Run one, run-one again when it ends, thus maintaining $degree active processes at a time
sub run-one-process {
my $item = @items.shift // return;
my $proc = Proc::Async.new('echo', "processing $item");
my @output;
# Capture output
whenever $proc.stdout.lines { push @output, $_; }
# Print all the output, then start the next process
whenever $proc.start {
@output.join("\n").say;
run-one-process
}
}
}
旧答案:
基于Jonathan Worthington在Perl 6中的并行,并发和异步(video,slides),这听起来很像 < em> parallelism (即选择一次做多件事;参见幻灯片18)。 Asynchrony 正在对未来的事情做出反应,我们无法控制时机;参见幻灯片39和40.正如@raiph在他的评论中所指出的,你可以有一个,另一个或两者。
如果您关心结果的顺序,请使用hyper
,但如果订单不重要,请使用race
。
在这个改编自Jonathan Worthington's slides的示例中,您构建了一个步骤流程,其中使用4个工作人员以32个文件名的批量处理数据:
sub MAIN($data-dir) {
my $filenames = dir($data-dir).race(batch => 32, degree => 4);
my $data = $filenames.map(&slurp);
my $parsed = $data.map(&parse-climate-data);
my $european = $parsed.grep(*.continent eq 'Europe');
my $max = $european.max(by => *.average-temp);
say "$max.place() is the hottest!";
}