在Perl 6中是否有类似Go goroutines的功能?

huangapple go评论87阅读模式
英文:

Is there an equivalent to Go goroutines in Perl6?

问题

我可以看到

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

在我的系统上创建了大约十几个moar线程,并将它们用作承诺的池,但我想像Go一样同时启动它们。这可能吗?

英文:

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?

答案1

得分: 6

<!-- language-all: lang-perl6 -->

据我了解,goroutines是一种非常底层的构造。Perl中的大多数东西都不是非常底层的。

最接近你所想要的可能是直接使用Threads

my @r = do for ^100 { # 如果超过100,目前会中止
  Thread.start: { .say; sleep 3 };
}

# 实际上,该构造可能会创建多个线程
@r&gt;&gt;.finish;

不过,我强烈建议你不要这样做,因为它不太可组合。


如果你想要在等待3秒后打印出数字,我会使用Promise.in方法,它返回一个在指定秒数后完成的Promise。下面的示例似乎几乎同时创建了500个线程,但实际上可能没有启动任何额外的线程。

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

Perl 6还有SuppliesChannels

# 每秒触发三个事件
my $supply = Supply.interval: 1/3;

react {
  # 不保证按顺序运行
  whenever $supply.grep(* %% 3) { print 'Fizz' }
  whenever $supply.grep(* %% 5) { print 'Buzz' }

  whenever $supply {
    sleep 1/10; # 稍微调整一下时间
    .put
  }
  
  whenever Promise.in(10) {
    say 'ten seconds have elapsed';
    done
  }
}

总的来说,异步构造的设计是为了隐藏一些在使用线程时必须处理的复杂问题。

实际上,使用线程的最简单方法之一可能就是在mapgrep方法调用之前添加hyperrace

my @r = (^50).hyper( :batch(5), :degree(10) ).map: { .say; sleep 1 }
# 如果你不关心@r的顺序,可以使用`race`而不是`hyper`
英文:

<!-- language-all: lang-perl6 -->

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&#39;s much over 100
  Thread.start: { .say; sleep 3 };
}

# The implementation may actually create several threads
# for this construct
@r&gt;&gt;.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: -&gt; $ { .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 &#39;Fizz&#39; }
  whenever $supply.grep(* %% 5) { print &#39;Buzz&#39; }

  whenever $supply {
    sleep 1/10; # fudge the timing a little
    .put
  }
  
  whenever Promise.in(10) {
    say &#39;ten seconds have elapsed&#39;;
    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&#39;t
# care about the order of @r

huangapple
  • 本文由 发表于 2015年8月11日 02:59:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/31927114.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定