Это зависит от того, как вы определяете «массив» и «долю». Что касается массивов, есть два случая, которые необходимо рассматривать отдельно:
- Массивы фиксированного размера (объявлено
my @a[$size]
); сюда входят многомерные массивы с фиксированными размерами (например, my @a[$xs, $ys]
). У них есть интересное свойство, заключающееся в том, что размер поддерживающей их памяти никогда не нужно изменять.
- Динамические массивы (объявленные
my @a
), которые растут по запросу. Под капотом они фактически используют некоторое количество блоков памяти с течением времени по мере их роста.
Что касается обмена, есть также три случая:
- Случай, когда несколько потоков соприкасаются с массивом за время его существования, но только один может касаться его одновременно из-за какого-либо механизма управления параллелизмом или общей структуры программы. В этом случае массивы никогда не используются совместно в смысле «параллельных операций с использованием массивов», поэтому нет возможности иметь гонку данных.
- Вариант только для чтения, неленивый. Здесь несколько одновременных операций обращаются к неленивому массиву, но только для его чтения.
- Случай чтения / записи (в том числе, когда чтение действительно вызывает запись, потому что массиву было назначено что-то, что требует ленивой оценки; обратите внимание, что это никогда не может произойти для массивов фиксированного размера, поскольку они никогда не ленивы).
Тогда мы можем резюмировать безопасность следующим образом:
| Fixed size | Variable size |
---------------------+----------------+---------------+
Read-only, non-lazy | Safe | Safe |
Read/write or lazy | Safe * | Not safe |
Знак * указывает на то, что, хотя это безопасно с точки зрения Perl 6, вы, конечно, должны убедиться, что не делаете противоречивых вещей с одними и теми же индексами.
Таким образом, массивы фиксированного размера, которые вы можете безопасно совместно использовать и назначать элементам из разных потоков, «не проблема» (но будьте осторожны с ложным совместным использованием, которое может заставить вас заплатить за это серьезное снижение производительности). Для динамических массивов это безопасно только в том случае, если они будут считываться только в течение периода, когда они совместно используются, и даже тогда, если они не ленивы (хотя данное назначение массива в основном нетерпеливое, вы вряд ли попадете в эту ситуацию случайно). Запись, даже в различные элементы, может привести к потере данных, сбоям или другому неправильному поведению из-за расширения операций.
Итак, рассматривая исходный пример, мы видим, что my @copy;
и my @length;
являются динамическими массивами, поэтому мы не должны писать в них в параллельных операциях. Однако такое случается, поэтому код может быть определен как небезопасный.
Другие сообщения, которые уже здесь, неплохо указывают на лучшие направления, но ни один не прибил кровавые детали.
person
Jonathan Worthington
schedule
04.05.2017
start
. - person Brad Gilbert   schedule 04.05.2017start
делает больше, чем просто что-то возвращает. Меня интересует параллелизм для параллельного выполнения кода, чтобы все ядра моего процессора работали. - person sid_com   schedule 04.05.2017