Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 在Perl 6中运行自馈送通道_Multithreading_Concurrency_Raku - Fatal编程技术网

Multithreading 在Perl 6中运行自馈送通道

Multithreading 在Perl 6中运行自馈送通道,multithreading,concurrency,raku,Multithreading,Concurrency,Raku,我想在一个通道上设置多个并发运行的线程,并且这些线程中的每一个都应该为通道提供数据。其中一个线程将决定何时停止。然而,这是我最近一次这样做: use Algorithm::Evolutionary::Simple; my $length = 32; my $supplier = Supplier.new; my $supply = $supplier.Supply; my $channel-one = $supply.Channel; my $pairs-supply = $supply.

我想在一个通道上设置多个并发运行的线程,并且这些线程中的每一个都应该为通道提供数据。其中一个线程将决定何时停止。然而,这是我最近一次这样做:

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;
这在多次排放后停止。而且它可能不会同时运行。我使用通道而不是供给和抽头,因为它们不是并发运行的,而是异步运行的。我需要补给,因为我想有一个seudo通道,可以成对接收元素,如上所述;我还没见过用纯渠道做这件事的方法。 如果我将电源的
emit
更改为通道的
send
,则上面没有区别

这里有几个问题

  • 这些
    react
    块是否在不同的线程中运行?如果没有,那怎么做呢

  • 即使它们不是,为什么即使
    $pairs
    一直向通道发射信号,它也会停止

  • 我可以从单个项目通道自动创建“批处理”通道吗


  • 更新1:如果我从末尾删除
    $supplier.done
    ,它将只是阻塞。如果我创建一个,每次读取一个,它只是阻塞,什么也不做

    答案就在这里,精简到最低限度

    my Channel $c .= new;
    my Channel $c2 = $c.Supply.batch( elems => 2).Channel;
    my Channel $output .= new;
    my $count = 0;
    $c.send(1) for ^2;
    
    my $more-work = start react whenever $c2 -> @item {
        if ( $count++ < 32 ) {
            $c.send( @item[1]);
        my $sum = sum @item;
        $c.send( $sum );
        $output.send( $sum ); 
        } else {
        $c.close;
        }
    
    }
    await $more-work;
    loop {
        if my $item = $output.poll {
        $item.say
        } else {
        $output.close;
        }
        if $output.closed  { last };
    }
    
    my Channel$c.=new;
    我的通道$c2=$c.Supply.batch(elems=>2.Channel);
    我的频道$output.=新频道;
    我的$count=0;
    $c.send(1)用于^2;
    my$more work=开始在$c2->@物品时作出反应{
    如果($count++<32){
    $c.send(@item[1]);
    我的$sum=sum@项目;
    $c.send($sum);
    $output.send($sum);
    }否则{
    $c.close;
    }
    }
    等待更多的工作;
    环路{
    如果我的$item=$output.poll{
    $item.say
    }否则{
    $output.close;
    }
    如果$output.closed{last};
    }
    
    通过从一个通道(
    $c.supply
    )创建一个供应、将该供应分成两批(
    batch(elems=>2)
    )并将其转换回一个通道,使用每两个元素对第一个通道进行批处理的第二个通道。为输出创建第三个通道。 为了不耗尽电源并挂起通道,从第一个(实际上是唯一的)通道读取的每一个第二个元素都被放回那里。所以第二个通道是两次读取,它永远不会被挂起或等待新元素。 为每个新元素创建一个输出通道,并在需要时创建一个外部计数器来完成操作;该输出通道以非阻塞方式读取,当最后一行中没有剩余内容可读取时关闭。 要准确回答我最初的问题:

  • 是的,他们是,只是他们互相偷东西
  • 因为两个线程从同一个通道读取。第一个偶然发现一个元素的人读到它
  • 是的,通过将渠道转化为供应品,对其进行配料,然后再将其转化为渠道。请记住,它们不是复制品,它们将共享相同的元素
    您可以使用
    start react where…{…}
    而不是
    start{react{where…{…}}
    以下是如何获得从另一个通道成对发射的通道:
    my channel$c.=new$c、 为^20发送($)$c、 接近;我的频道$c2.=新频道;my$work=start{$c2.send:$\$c.List.rotor(2);$c2.close;CATCH{default{$c2.fail($\}}。比如说c2.1美元;等待$work
    -检查是否需要:转子呼叫也有部分。@BradGilbert没有区别。为什么效果更好?@timotimo这不是我想要的。如果我这样修改它,
    If($count++<100){$c.send($count);}else{$c.close;}
    ,这样它会继续向第一个通道馈电,而第二个通道则会在最初的20个数字之后挂起<代码>$count在此之前将被初始化为0。更接近我想要的,但仍然无法满足。它只是丢弃了一些对,并在处理第一个40@timotimo后停止