perl6 Общий подход к изменению массива при его цикле - PullRequest
0 голосов
/ 19 декабря 2018

Быстрый вопрос: Безопасно ли в Perl6 (в отличие от perl5 или других языков) циклически перемещаться по массиву при его изменении?Например, если у меня есть массив веб-сайтов для загрузки, и я добавляю неудачные загрузки в конец массива для повторной загрузки, будет ли Perl6 вести себя как ожидалось?(У меня есть около 50 тыс. Ссылок для загрузки, и попытка протестировать все это заняло бы много времени.)

Если не безопасно, каков общий подход?Я думал о сохранении ссылок прерванных загрузок в другом массиве и перебираю этот массив после того, как исходный массив был создан.Тем не менее, это похоже на то, как лиса гонится за хвостом, потому что мне приходится хранить неудачные загрузки в другом массиве (или перезаписывать исходный массив).

Большое спасибо !!!

lisprog

1 Ответ

0 голосов
/ 19 декабря 2018

Это определенно безопасно в однопоточной среде:

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

Обратите внимание, что последний пример не будет работать должным образом, поскольку все потоки start ed должны быть await Эд где-то внутри цикла.Считайте, что это просто базовая демонстрация.

Тем не менее, при любой возможности блокировки обычно избегают.Лучшее решение будет использовать блоки Channel и react/whenever.

...