我想在一个通道上同时设置多个线程,并且每个线程也应该在通道上进行输入。其中一个线程将决定何时停止。但是,这是我最接近实现它的方法:
use Algorithm::Evolutionary::Simple;
my $length = 32;
my $supplier = Supplier.new;
my $supply = $supplier.Supply;
my $channel-one = $supply.Channel;
my $pairs-supply = $supply.batch( elems => 2 );
my $channel-two = $pairs-supply.Channel;
my $single = start {
react {
whenever $channel-one -> $item {
say "via Channel 1:", max-ones($item);
}
}
}
my $pairs = start {
react {
whenever $channel-two -> @pair {
my @new-chromosome = crossover( @pair[0], @pair[1] );
say "In Channel 2: ", @new-chromosome;
$supplier.emit( @new-chromosome[0]);
$supplier.emit( @new-chromosome[1]);
}
}
}
await (^10).map: -> $r {
start {
sleep $r/100.0;
$supplier.emit( random-chromosome($length) );
}
}
$supplier.done;
这将在一定数量的发射后停止。而且它可能不会同时运行。我使用通道而不是供应和插头,因为这些不是并发运行,而是异步运行。我需要供应,因为我想要一个伪通道,以成对地获取元素,就像上面所做的那样;我没有看到使用纯通道的方法来实现这一点。如果我将供应的
emit
更改为通道的send
,则上述内容没有区别。因此,这里有几个问题:
1.这些
react
块是否在不同的线程中运行?如果不是,有什么方法可以做到这一点?2.即使它们不是,为什么它会停止,即使
$pairs
一直向通道发出信号?3.我能否从单项通道自动创建“批量”通道?
更新1:如果我从末尾删除
$supplier.done
,它将只会阻塞。如果我在每次读取时创建一个承诺,它只会阻塞并且什么也不做。
start react whenever ... { ... }
,而不是start { react { whenever ... { ... } } }
。 - Brad Gilbertmy Channel $c .= new; $c.send($_) for ^20; $c.close; my Channel $c2 .= new; my $work = start { $c2.send: $_ for $c.List.rotor(2); $c2.close; CATCH { default { $c2.fail($_) } } }; .say for $c2.List; await $work
- 检查一下你是否也想在rotor调用中使用 :partial。 - timotimoif ( $count++ < 100 ) { $c.send( $count ); } else { $c.close; }
以便它继续向第一个频道提供数据,然后再传递给第二个频道,在最初的20个数字之后它就会挂起。在此之前,$count
将被初始化为0。 - jjmerelo