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

jjm*_*elo 5 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;
}
Run Code Online (Sandbox Code Playgroud)

(这是因为我没有关闭频道,但请不要看那个).无论我做什么,这都输出:

In thread 4
? 6995966328
In thread 4
? 12323793510
In thread 4
? 5473561506
Run Code Online (Sandbox Code Playgroud)

因此,它始终使用单个线程并按顺序处理事物,而不是并行处理.有没有办法做到这一点?即使我startwhenever块内的线程,结果也会完全一样......

Jon*_*ton 9

react/ whenever构建体用于在时间和在充满处理一个消息.关键在于,react由于这个原因,该区块内的状态是安全的.

可以让多个工人从一个人那里读书Channel; 他们只需要设置如下:

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

这种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;
    }
}
Run Code Online (Sandbox Code Playgroud)

react此方法中没有机会对不同的数据源做出反应(之所以Channel使用react它的原因主要是因为您可以使用它们并同时使用异步数据源,或者可能同时处理多个通道).但是如果你不需要,那么代码中的for方式就更简单了几乎肯定更快(并且,就像react在循环中竞争对象中的项目Channel并且在它关闭时优雅地终止).