Руководящие принципы Python для многопроцессорных систем, кажется, конфликтуют: разделяете память или мариноваете? - PullRequest
0 голосов
/ 04 июня 2018

Я играю с модулем Python multiprocessing, чтобы массив (только для чтения) распределялся между несколькими процессами.Моя цель - использовать multiprocessing.Array для распределения данных, а затем получить мой код разветвленный (forkserver), чтобы каждый работник мог читать прямо из массива и выполнять свою работу.

Читая Руководство по программированию , я немного запутался.

Сначала говорится:

Избегайте общего состояния

Насколько это возможноследует избегать смещения больших объемов данных между процессами.

Вероятно, лучше использовать очереди или каналы для связи между процессами, а не использовать примитивы синхронизации более низкого уровня.

А потом, пара строк ниже:

Лучше наследовать, чем мариновать / расщеплять

При использовании методов запуска spawn или forkserver многие типы из многопроцессорной обработки должны быть выбраны так, чтобычто дочерние процессы могут их использовать.Однако, как правило, следует избегать отправки общих объектов другим процессам с использованием каналов или очередей.Вместо этого вы должны расположить программу так, чтобы процесс, которому требуется доступ к общему ресурсу, созданному в другом месте, мог унаследовать его от процесса-предка.

Насколько я понимаю, очереди и трубы маринованные предметы.Если так, не противоречат ли эти два руководства?

Спасибо.

1 Ответ

0 голосов
/ 05 июня 2018

Указание second относится к вашему случаю использования.

Первое напоминает вам, что это не многопоточность, когда вы управляете общими структурами данных с помощью блокировок (или атомарных операций).).Если вы используете Manager.dict() (что на самом деле SyncManager.dict) для всего, каждое чтение и запись должны иметь доступ к процессу менеджера, и вам также нужна синхронизация, типичная для многопоточных программ (которая сама по себе может стоить дороже из-за перекрестного взаимодействия).-process).

Во втором руководстве предлагается наследовать общие, доступные только для чтения объекты через fork;в случае forkserver это означает, что вы должны создавать такие объекты перед вызовом set_start_method, поскольку все рабочие являются дочерними элементами процесса, созданного в то время.

Отчеты оудобство использования такого совместного использования смешано в лучшем случае , но если вы можете использовать небольшое число любого из C-подобных массивов (например, numpy или стандартный array модуль)), вы должны увидеть хорошую производительность (потому что большинство страниц никогда не будут написаны для подсчета ссылок).Обратите внимание, что вам не нужно multiprocessing.Array здесь (хотя это может работать нормально), поскольку вам не нужно записи в одном параллельном процессе, чтобы быть видимым в другом.

...