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

时间:2018-03-30 16:30:55

标签: concurrency perl6

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

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

所以它始终使用单个线程并按顺序处理事物,而不是并行处理。有没有办法做到这一点?即使我startwhenever中的线程,结果也会完全相同......

1 个答案:

答案 0 :(得分:9)

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一样,循环竞争{{1}中的项目。 1}}并在关闭时优雅地终止。)