【问题标题】:perl6 General approach to modifying an array while looping through itperl6 在循环遍历数组时修改数组的一般方法
【发布时间】:2018-12-19 17:40:18
【问题描述】:

快速提问:在 Perl6(相对于 perl5 或其他语言)中,在修改数组时循环遍历数组是否安全?例如,如果我有一组网站要下载,并且我将失败的下载添加到数组的末尾以重新下载,perl6 会按预期运行吗? (我有大约 50k 链接要下载,并且尝试全部测试会很耗时。)

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

非常感谢!!!

lisprog

【问题讨论】:

标签: arrays loops raku


【解决方案1】:

在单线程环境下绝对安全:

my @a = ^5;
for @a { 
    @a.push: $_ + 10 if $_ < 30
}
say @a

[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

请注意,最后一个示例不会按预期工作,因为所有started 线程必须在循环内的某个位置awaited。将其视为一个基本演示。

然而,通常尽可能避免锁定。更好的解决方案是使用 Channelreact/whenever 块。

【讨论】:

  • 一个涉及react/whenever的简单例子可以在gist.github.com/jnthn/b358ebfb6ea6c366834896b9f62ba92b中找到。需要注意的一件有趣的事情是,它根本不必保留一系列工作要做,也不必担心终止(当没有未完成的请求时,react 块自然会终止)。
  • 非常感谢 Vadim Belman 和 Jonathan Worthington 的澄清。你的建议真的很有帮助。我会调查反应/任何时候。谢谢!!!
  • 在多线程的情况下,也可以使用Channel(线程安全队列)代替数组,不用担心Locking。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-04
  • 1970-01-01
  • 2019-07-10
  • 2013-12-12
  • 1970-01-01
相关资源
最近更新 更多