Чтобы выполнить задачи параллельно, multiprocessing
«перехватывает» функцию задачи.В вашем случае эта «функция задачи» имеет вид lambda file: getThing(file, 2, map)
.
К сожалению, для вас по умолчанию лямбда-функции не могут быть перехвачены в python (см. Также этот пост стекопотоков ).Позвольте мне проиллюстрировать проблему с минимальным битом кода:
import multiprocessing
l = range(12)
def not_a_lambda(e):
print(e)
def main():
with multiprocessing.Pool() as pool:
pool.map(not_a_lambda, l) # Case (A)
pool.map(lambda e: print(e), l) # Case (B)
main()
В Случай A у нас есть правильная, свободная функция, которую можно активировать, таким образом, операция pool.map
будет работать,В случае B у нас есть лямбда-функция, и происходит сбой.
Одним из возможных решений является использование правильной функции области видимости модуля (например, моего not_a_lambda
).Другим решением является использование стороннего модуля, такого как укроп , для расширения функций травления.В последнем случае вы будете использовать, например, pathos вместо обычного multiprocessing
модуля.Наконец, вы можете создать класс Worker
, который будет собирать ваше общее состояние в качестве членов.Это может выглядеть примерно так:
import multiprocessing
class Worker:
def __init__(self, mutex, map):
self.mutex = mutex
self.map = map
def __call__(self, e):
print("Hello from Worker e=%r" % (e, ))
with self.mutex:
k, v = e
self.map[k] = v
print("Goodbye from Worker e=%r" % (e, ))
def main():
manager = multiprocessing.Manager()
mutex = manager.Lock()
map = manager.dict()
# there is only ONE Worker instance which is shared across all processes
# thus, you need to make sure you don't access / modify internal state of
# the worker instance without locking the mutex.
worker = Worker(mutex, map)
with multiprocessing.Pool() as pool:
pool.map(worker, l.items())
main()