Мутипроцессинг Python с большими общими данными - PullRequest
0 голосов
/ 18 декабря 2018

Я использую python для разработки приложения для обработки данных с использованием модуля mutliprocessing, код выглядит следующим образом:

import multiprocessing

globalData = loadData() #very large data 

def f(v):
    global globalData
    return someOperation(globalData,v)

if __name__ == '__main__':
    pool = multiprocessing.Pool()
    arr = loadArray() #some big list
    res = pool.map(f,arr)

Проблема в том, что для всех дочерних процессов требуются одинаковые глобальные данные для обработкифункция, поэтому он загружает ее и занимает много времени, каково лучшее решение для обмена этими данными среди всех дочерних процессов, так как они уже загружены в родительский процесс?

Ответы [ 2 ]

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

Многопроцессорная обработка в ms-windows работает иначе, чем в UNIX-подобных системах.

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

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

Дело в том, что MS-Windows не имеет fork.Вместо этого CreateProcess.Так в ms-windows это происходит:

Родительский процесс запускает новый процесс интерпретатора Python.Дочерний процесс будет наследовать только те ресурсы, которые необходимы для запуска метода run () объектов процесса.В частности, ненужные файловые дескрипторы и дескрипторы от родительского процесса не будут наследоваться.Запуск процесса с использованием этого метода довольно медленный по сравнению с использованием fork или forkserver.

Таким образом, поскольку в вашей функции есть ссылки на ваши глобальные данные, они будут загружены. Но каждый дочерний процесс будет загружать его отдельно .

То, что вы можете попробовать, - это загрузить ваши процессы, используя mmap с ACCESS_READ.Я бы ожидал , что подсистема памяти ms-windows достаточно умна, чтобы загружать данные только один раз, если один и тот же файл загружен несколькими процессами.

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

Я также новичок в python, но если я понимаю ваш вопрос, это очень просто: в следующем скрипте мы используем 5 рабочих, чтобы получить квадрат первых 10000 чисел.

import multiprocessing

globalData = range(10000) #very large data 

def f(x):
  return x*x

if __name__ == '__main__':
    pool = multiprocessing.Pool(5)
    print(pool.map(f,globalData))
...