Делить объект python между многопроцессорными в python3
Здесь я создаю программу "производитель-клиент", родительский процесс (производитель) создает множество дочерних процессов (потребитель), затем родительский процесс читает файл и передает данные дочернему процессу.
но тут возникает проблема с производительностью, передача сообщений между процессами слишком большая (я думаю).
например, исходные данные объемом 200 МБ, чтение и предварительная обработка родительского процесса обойдутся менее чем в 8 секунд, чем просто передача данных в дочерний процесс посредством многопроцессорной обработки. pipe будет стоить еще 8 секунд, а дочерние процессы будут выполнять оставшуюся работу, всего за 3-4 секунды.
Итак, полный рабочий процесс стоит менее 18 секунд и более 40% затрат времени на обмен данными между процессами, это намного больше, чем я думал, и я попробовал многопроцессорность. Очередь и менеджер, они хуже.
Я работаю с Windows7 / Python3.4. У меня был Google в течение нескольких дней, и POSH может быть хорошим решением, но он не может собрать с python3.4
там у меня 3 способа:
1. Есть ли какой-нибудь способ, которым объект Python может делиться напрямую между процессами в Python3.4? как ПОШ
или же
2. возможно ли передать "указатель" объекта на дочерний процесс, а дочерний процесс может восстановить "указатель" на объект python?
или же
3.multiprocess.Array может быть допустимым решением, но если я хочу поделиться сложной структурой данных, такой как список, как это работает? я должен создать новую базу классов и предоставить интерфейсы в виде списка?
Edit1: я пробовал 3-й способ, но он работает хуже.
Я определил эти значения:
p_pos = multiprocessing.Value ('i') # позиция записи производителя
c_pos = multiprocessing.Value('i') # позиция чтения клиента
databuff = multiprocess.Array('c',buff_len) # общий буфер
и две функции:
send_data (MSG)
получить данные()
в функции send_data (родительский процесс) он копирует msg в databuff и отправляет начальную и конечную позиции (два целых числа) дочернему процессу через pipe.
чем в функции get_data (дочерний процесс), он получил две позиции и скопировал сообщение из буфера данных.
в конце концов, это стоит вдвое больше, чем просто использовать трубу @_@
Изменить 2:
Да, я пробовал Cython, и результат выглядит хорошо.
Я просто изменил суффикс скрипта Python на.pyx и скомпилировал его, и программа ускорилась на 15%.
Без сомнения, я встретил ошибки "Невозможно найти vcvarsall.bat" и "Системе не удалось найти указанный файл", и я потратил целый день на то, чтобы решить первый и заблокировать второй.
Наконец, я нашла Сайтера, и все проблемы ушли ^_^.
2 ответа
Я был у тебя пять месяцев назад. Я несколько раз оглядывался по сторонам, но мой вывод о том, что многопроцессорность с Python имеет именно ту проблему, которую вы описываете:
- Трубы и Очередь хороши, но не для больших объектов из моего опыта
- Прокси-объекты Manager() медленны, за исключением массивов и ограничены. если вы хотите совместно использовать сложную структуру данных, используйте пространство имен, как это делается здесь: многопроцессорность в python - совместное использование большого объекта (например, pandas dataframe) между несколькими процессами
- Manager() имеет общий список, который вы ищете: https://docs.python.org/3.6/library/multiprocessing.html
- В Python нет указателей или реального управления памятью, поэтому вы не можете использовать отдельные ячейки памяти
Я решил эту проблему, изучая C++, но, вероятно, это не то, что вы хотите прочитать...
Для передачи данных (особенно больших массивов с нулями) в дочерний процесс я думаю, что mpi4py может быть очень эффективным, поскольку я могу работать непосредственно с объектами, похожими на буфер.
Пример использования mpi4py для порождения процессов и общения (с использованием также трио, но это другая история) можно найти здесь.