multithreading - 动态变量和 promise

标签 multithreading raku

似乎动态变量并不总是在线程中的子例程调用中幸存下来:

sub foo($x, &y = &infix:<+>) {
  my &*z = &y;
  bar($x);
}

sub bar ($x) {
    say &*z($x,$x);

    my $promise = start { bar($x-1) if $x > 0 }
    await $promise;

    # bar($x-1) if $x > 0    # <-- provides the expected result: 6, 4, 2, 0
}
foo(3); # 6, 4, Dynamic variable &*z not found

使用更全局范围的变量也有效,因此并不是所有变量都丢失了 - 它似乎特定于动态:
our &b;

sub foo($a, &c = &infix:<+>) {
  &b = &c;
  bar($a);
}

sub bar ($a) {
    say &b($a,$a);
    my $promise = start { bar($a-1) if $a > 0 }
    await $promise;
}

foo(3); # 6, 4, 2, 0

一旦在 foo() 中设置了变量, 在 bar() 中读取没有问题.但是当 bar()从 promise 内部调用,&*z 的值不是在第一层递归而是在第二层消失。

我感觉到一个错误,但也许我在递归/动态变量/线程之间做一些奇怪的事情,这让事情变得一团糟。

最佳答案

在当前语义下,start将捕获它被调用的上下文。如果动态变量查找在线程堆栈上失败 start在(线程池中的一个)上执行,然后它会回退到查看 start 时捕获的动态范围块被安排。

start块是在另一个 start 的执行过程中创建的块,同样的事情发生。但是,两者之间没有关系,这意味着“外部”start 捕获的上下文块也不会被搜索。虽然人们可以争辩说这种情况发生,但这样做似乎有潜在的问题。考虑这个例子:

sub tick($n = 1 --> Nil) {
    start {
        await Promise.in(1);
        say $n;
        tick($n + 1);
    }
}
tick();
sleep;

这是一种(不完全是惯用的)每秒产生一次滴答声的方式。被内start为了保持对外部状态的引用,出于动态变量查找的目的,该程序将在内存中建立一个长度不断增加的链,这似乎是一种不受欢迎的行为。

关于multithreading - 动态变量和 promise ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57581749/

相关文章:

r - 是否有可能使用Mixins在Raku中复制R的 'named vectors'概念的简便方法?

regex - Perl6 : Confused about BagHash/Matching

regex - 匹配一个连接点使得 Match 不可变

multithreading - 从具有多个线程的文件中读取是否被视为 Rust 中的未定义行为?

c# - 调用方法的结果到主线程

java - 从 MATLAB 执行时如何为 JAVA 程序分配更多内存?

regex - perl6 彩色匹配,一些正则表达式插值有效,有些无效;颜色代码不一致

java - 在 Java 关键部分中,我应该同步什么?

.NET 字典 : is only enumerating thread safe?

raku - 在 Perl 6 中用另一个数组的元素过滤一个数组的元素