どういうわけか、Queue
どこででもこれを行う方法の一般的な例を見つけることができませんでした(Pythonのドキュメントの例でも複数のプロセスを生成しません)。
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
子プロセスからの戻り値を格納するために使用できる、スレッドセーフなブロッキングキューです。したがって、各プロセスにキューを渡す必要があります。ここでそれほど明白ではないことは、esまたはキューがいっぱいになってすべてをブロックするget()
前に、キューから削除する必要がjoin
あるProcess
ことです。
オブジェクト指向の人向けの更新(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)
multiprocessing.Queue
ではなくを使用することをお勧めしManager
ます。を使用するにManager
は、まったく新しいプロセスを生成する必要Queue
があります。