perl6循环遍历时修改数组的一般方法

lis*_*tor 7 arrays loops perl6

快速问题:Perl6(与perl5或其他语言相反)在修改数组时循环播放是否安全?例如,如果我有一系列要下载的网站,并且我将失败的下载添加到阵列的末尾以重新下载,那么perl6会按预期运行吗?(我有大约50k的链接下载,并试图全部测试将耗费时间.)

如果不安全,什么是一般方法?我一直在考虑将中断下载的链接存储在另一个数组中,并在原始数组完成后循环遍历该数组.然而,这就像一只追逐尾巴的狐狸,因为我必须在另一个阵列中存储失败的下载(或覆盖原始数组).

非常感谢你 !!!

lisprog

Vad*_*man 6

它在单线程环境中绝对安全:

my @a = ^5;
for @a { 
    @a.push: $_ + 10 if $_ < 30
}
say @a
Run Code Online (Sandbox Code Playgroud)

[1 2 3 4 11 12 13 14 21 22 23 24 31 32 33 34]

在多线程环境中(最好在您的任务中使用),没有什么是理所当然的.因此,将新元素附加到数组最好包含在Lock:

my @a = ^5;
my Lock $l .= new;
for @a {
    start {
        ... # Do your work here 
        $l.protect: {
            @a.push: $_ with $site
        }
    }
}
say @a
Run Code Online (Sandbox Code Playgroud)

请注意,最后一个示例将无法按预期工作,因为start必须await在循环内的某处编辑所有ed线程.将它视为基本演示.

然而,通常尽可能避免锁定.一个更好的解决方案是使用Channelreact/whenever阻止.

  • 可以在https://gist.github.com/jnthn/b358ebfb6ea6c366834896b9f62ba92b中找到一个涉及`react`/`never`的简单示例.有一点需要注意的是,它根本不需要保留一系列工作,也不必担心终止(当没有未完成的请求时,`react`块自然会终止). (7认同)