React 在处理通道时使用单线程

React uses a single thread when processing a channel

我的意图是让不同的线程同时从一个通道读取,并异步处理。我认为这可以解决问题:

my Channel $KXGA .= new;

for ^100 {
    $KXGA.send( (100000..200000).pick );
}

my $sums = start react whenever $KXGA -> $number {
    say "In thread ", $*THREAD.id;
    say "→ ", (^$number).sum;
}

(因为我没有关闭频道所以挂了,但请不要看那个)。这输出,无论我做什么:

In thread 4
→ 6995966328
In thread 4
→ 12323793510
In thread 4
→ 5473561506

所以它总是使用单个线程并按顺序处理事情,而不是并行处理。有什么办法吗?即使我 start whenever 块中的线程,结果也将完全相同...

react/whenever 构造用于一次完整地处理一条消息。关键是 react 块中保存的状态因此是安全的。

可以让多个工作人员读取一个Channel;他们只需要按如下方式设置:

my @sums;
for ^4 {
    push @sums, start react whenever $KXGA -> $number {
        say "In thread ", $*THREAD.id;
        say "→ ", (^$number).sum;
    }
}

这种react方法,当与use v6.d.PREVIEW一起使用时,其优点是当工作较少时,它实际上根本不会占用4个线程,它们可以与其他池中的线程一起使用工作。相反,如果整个应用程序只是处理来自 Channel 的内容,仅此而已,您将拥有更少的开销和更好的局部性,只需:

my @sums;
for ^4 {
    push @sums, start for $KXGA.list -> $number {
        say "In thread ", $*THREAD.id;
        say "→ ", (^$number).sum;
    }
}

react 不同,在这种方法中没有机会对不同的数据源做出反应(Channel 使用 react 的原因主要是您可以使用它们并同时工作也使用异步数据源,或者一次处理多个通道)。但是,如果您不需要,那么 for 方法在代码中稍微简单一点,而且几乎肯定更快(而且,与 react 一样,循环会竞争 Channel 并在关闭时优雅地终止)。