如何限制Perl 6中Proc :: Async产生的并发进程数?

Cyb*_*ull 6 asynchronous perl6

我想在脚本的子任务中处理文件列表,并且正在使用它Proc::Async来生成完成工作的子过程。缺点是,如果我要处理的文件列表很大,它将产生许多子进程。我想知道如何限制Proc::Async产生的并发子进程的数量?

Chr*_*oms 4

Proc::Async您可以使用这种 React 块技术显式限制进程数量,Jonathan Worthington在 2019 年德国 Perl 研讨会上的并发/并行/异步演讲中演示了该技术(例如,请参见幻灯片 39)。我echo N在下面的代码中使用 Linux 命令作为我的“外部进程”。

#!/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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

旧答案:

根据 Jonathan Worthington 的演讲Perl 6 中的并行性、并发性和异步性视频幻灯片),这听起来很像并行性(即选择同时执行多项操作;请参阅幻灯片 18)。异步是对未来的事情做出反应,而其时间安排是我们无法控制的;请参阅幻灯片 39 和 40。正如 @raiph 在他的评论中指出的那样,您可以选择其中之一,或者两者都选择。

如果您关心结果的顺序,则使用hyper,但如果顺序不重要,则使用race

在此示例中,改编自Jonathan Worthington 的幻灯片,您构建了一个步骤管道,其中使用 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!";
}
Run Code Online (Sandbox Code Playgroud)