无序
Raku 没有有序的消息队列。它有一个需要做的事情的无序列表。
# schedule them to run at the same second
# just to make it more likely that they will be out of order
my $wait = now + 1;
my @run;
for 1..20 -> $n {
push @run, Promise.at($wait).then: {say $n}
}
await @run;
这可以按任何顺序打印数字。
1
2
3
4
5
6
7
8
11
12
13
14
15
16
17
18
9
10
19
20
Raku 实际上是多线程的。如果你给它足够的工作,它会使用你所有的 cpu 核心。
这意味着永远无法说在队列中当前的所有内容完成后运行它。
即使我只是使用start,它有时也会出现问题。
my @run;
for 1..20 -> $n {
push @run, start {say $n}
};
await @run;
在它开始乱序打印之前你可以运行数百次,但它最终会这样做。
即使你进入低级并使用$*SCHEDULER.cue,也不能保证它会在其他所有内容之后运行。
my @nums;
for 1..100 -> $n {
$*SCHEDULER.cue: {push @nums, $n; say $n}
}
say @nums;
不仅可能出现乱序,@nums 数组可能不会包含所有值,因为每个线程都可能破坏另一个线程正在执行的操作。
在底层,安排运行的 Promise 方法最终会以某种方式调用 $*SCHEDULER.cue。
安排别的事情
您可以告诉 Raku 在执行其他操作后运行您的代码。
my $p = Promise.in(1);
my $p2 = $p.then: {say 'first'}
my $p3 = $p.then: {say 'second'}
react {
whenever start say('first') {
whenever start say('second') {
}
}
}
你需要有那个东西的参考。
慢
如果 Raku 确实有办法在当前安排的事件之后运行事物,那么它必须跟踪正在运行的事物并确保您的代码在它们完成之前不会运行。
my $a = start {
# pointless busy-work that takes two seconds
my $wait = now + 2;
my $n = 0;
while now ≤ $wait {
$n++
}
say $n; # make sure the loop doesn't get optimized away
say 'first';
}
my $b = start say 'second';
await $a, $b;
second
1427387
first
如果这确保$b 在$a 之后运行,那么整整两秒内都不会对$b 执行任何操作。
相反,它只是导致$b 在另一个线程上运行,因为正在处理$a 的线程当前正忙。
这是一件好事,因为如果 $b 也很慢怎么办。我们将安排两个缓慢的事情按顺序而不是并行运行。
Javascript
我认为它目前在 Javascript 中工作的唯一原因是因为它似乎没有利用多个 cpu 内核。或者它有类似 GIL 的东西。
我编写的 Raku 代码使我的 4 核 CPU 的利用率达到 500%。 (英特尔超线程 CPU,其中一个内核似乎是 2 个内核)
我不确定您是否可以对单个 Javascript 程序执行相同的操作。