Pour une raison quelconque, je n'ai pas pu trouver d'exemple général sur la façon de faire cela avec Queue
n'importe où (même les exemples de la doc de Python ne génèrent pas de processus multiples), alors voici ce que j'ai réussi à faire fonctionner après une dizaine d'essais :
def add_helper(queue, arg1, arg2): # the func called in child processes
ret = arg1 + arg2
queue.put(ret)
def multi_add(): # spawns child processes
q = Queue()
processes = []
rets = []
for _ in range(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
est une file d'attente bloquante et thread-safe que vous pouvez utiliser pour stocker les valeurs de retour des processus enfants. Vous devez donc passer la file d'attente à chaque processus. Une chose moins évidente ici est que vous devez get()
de la file d'attente avant de join
el Process
es, sinon la file d'attente se remplit et bloque tout.
Mise à jour pour ceux qui sont orientés objet (testé dans Python 3.4) :
from multiprocessing import Process, Queue
class Multiprocessor():
def __init__(self):
self.processes = []
self.queue = Queue()
@staticmethod
def _wrapper(func, queue, args, kwargs):
ret = func(*args, **kwargs)
queue.put(ret)
def run(self, func, *args, **kwargs):
args2 = [func, self.queue, args, kwargs]
p = Process(target=self._wrapper, args=args2)
self.processes.append(p)
p.start()
def wait(self):
rets = []
for p in self.processes:
ret = self.queue.get()
rets.append(ret)
for p in self.processes:
p.join()
return rets
# tester
if __name__ == "__main__":
mp = Multiprocessor()
num_proc = 64
for _ in range(num_proc): # queue up multiple tasks running `sum`
mp.run(sum, [1, 2, 3, 4, 5])
ret = mp.wait() # get all results
print(ret)
assert len(ret) == num_proc and all(r == 15 for r in ret)