在Perl6中有与Go goroutines等效的东西吗?

问题描述:

I can see that

perl6 -e '@r = do for ^500 {start { .say; sleep 3 }}; await @r'

makes about a dozen of moar threads on my system and use them as pool for promises, but I would like to start them all at once like in Go. Is that possible?

我可以看到 p>

  perl6 -e'@r  =做^ 500 {开始{.say; 睡觉3}};  await @r'
  code>  pre> 
 
 

在我的系统上制作大约12个线程,并将它们用作承诺池,但是我想 像Go中一样立即启动它们。 可以吗? p> div>

From what I understand goroutines are a very low level construct.
Most things in Perl are not very low level.

The closest to what you think you want is probably to directly use Threads.

my @r = do for ^100 { # currently aborts if it's much over 100
  Thread.start: { .say; sleep 3 };
}

# The implementation may actually create several threads
# for this construct
@r>>.finish;

I highly recommend you not do that though as it is not very composable.


If you instead wanted to print out the numbers after waiting 3 seconds I would have used the .in method of Promise which returns a Promise that will be kept in that many seconds.
This example appears to create 500 threads nearly simultaneously, but may not actually start any additional threads.

my @r = (^500).map: {
  Promise.in(3).then: -> $ { .say }
}
await @r;

Perl 6 also has Supplies and Channels

# get three events fired each second
my $supply = Supply.interval: 1/3;

react {
  # not guaranteed to run in order.
  whenever $supply.grep(* %% 3) { print 'Fizz' }
  whenever $supply.grep(* %% 5) { print 'Buzz' }

  whenever $supply {
    sleep 1/10; # fudge the timing a little
    .put
  }

  whenever Promise.in(10) {
    say 'ten seconds have elapsed';
    done
  }
}

In general the design of asynchronous constructs are there to hide some of the hairier things you have to handle with threads.

In fact one of the easiest ways to use threads may well be to just add hyper or race before a map or grep method call:

my @r = (^50).hyper( :batch(5), :degree(10) ).map: { .say; sleep 1 }
# use `race` instead of `hyper` if you don't
# care about the order of @r