if __name__ == "__main__": manager = multiprocessing.Manager() return_dict = manager.dict() jobs = [] for i inrange(5): p = multiprocessing.Process(target=worker, args=(i, return_dict)) jobs.append(p) p.start()
for proc in jobs: proc.join() print(return_dict.values())
Я думаю, что подход, предложенный sega_sai, является лучшим. Но для этого действительно нужен пример кода, поэтому здесь:
import multiprocessing from os import getpid
defworker(procnum): print('I am number %d in process %d' % (procnum, getpid())) return getpid()
if __name__ == '__main__': pool = multiprocessing.Pool(processes = 3) print(pool.map(worker, range(5)))
Который выведет возвращаемые значения:
I am number 0 in process 19139 I am number 1 in process 19138 I am number 2 in process 19140 I am number 3 in process 19139 I am number 4 in process 19140 [19139, 19138, 19140, 19139, 19140]
Если вы знакомы с map (встроенный Python 2), это не должно быть слишком сложным. В противном случае взгляните на ссылку sega_Sai .
Обратите внимание, как мало кода требуется. (Также обратите внимание, как процессы используются повторно.)
Ответ 3
Для всех, кто ищет, как получить значение из Process используя Queue:
import multiprocessing
ret = {'foo': False}
defworker(queue): ret = queue.get() ret['foo'] = True queue.put(ret)
if __name__ == '__main__': queue = multiprocessing.Queue() queue.put(ret) p = multiprocessing.Process(target=worker, args=(queue,)) p.start() p.join() print(queue.get()) # Prints {"foo": True}
Обратите внимание, что в Windows или Jupyter Notebook с помощью multithreading вы должны сохранить это как файл и выполнить файл. Если вы сделаете это в командной строке, вы увидите ошибку, подобную этой:
AttributeError: Can't get attribute 'worker' on <module '__main__' (built-in)>
Ответ 4
По какой-то причине я нигде не смог найти общий пример того, как это сделать с Queue (даже примеры doc в Python не запускают несколько процессов), так что вот что у меня получилось примерно после 10 попыток:
from multiprocessing import Process, Queue
defadd_helper(queue, arg1, arg2): # the func called in child processes ret = arg1 + arg2 queue.put(ret)
defmulti_add(): # spawns child processes q = Queue() processes = [] rets = [] for _ inrange(0, 100): p = Process(target=add_helper, args=(q, 1, 2)) processes.append(p) p.start() for p in processes: ret = q.get() # will block rets.append(ret) for p in processes: p.join() return rets
Queue это блокирующая потокобезопасная очередь, которую вы можете использовать для хранения возвращаемых значений из дочерних процессов. Таким образом, вы должны передавать очередь каждому процессу. Что-то менее очевидное здесь заключается в том, что вам нужно get() из очереди, прежде чем вы join выполните Processes, иначе очередь заполнится и заблокирует все.
Обновление для тех, кто объектно-ориентирован (протестировано в Python 3.4):