私はpythonオブジェクト指向に不慣れで、既存のアプリケーションをオブジェクト指向バージョンに書き換えています。現在、開発者が増えており、コードがメンテナンスできなくなっているためです。
通常はマルチプロセッシングキューを使用しますが、この例から http://www.doughellmann.com/PyMOTW/multiprocessing/basics.html サブクラス化できることがわかりました_multiprocessing.Process
_なので、良いと思いますアイデアと私はこのようにテストするクラスを書きました:
コード:
_from multiprocessing import Process
class Processor(Process):
def return_name(self):
return "Process %s" % self.name
def run(self):
return self.return_name()
processes = []
if __name__ == "__main__":
for i in range(0,5):
p=Processor()
processes.append(p)
p.start()
for p in processes:
p.join()
_
ただし、値を取得できません。このようにキューを使用するにはどうすればよいですか?
編集:私は戻り値を取得し、Queues()
をどこに置くかを考えたいです。
multiprocessing.Process
_のサブクラス化:ただし、値を取得できません。このようにキューを使用するにはどうすればよいですか?
プロセスは結果を受け取るためにQueue()
を必要とします... _multiprocessing.Process
_をサブクラス化する方法の例は次のとおりです...
_from multiprocessing import Process, Queue
class Processor(Process):
def __init__(self, queue, idx, **kwargs):
super(Processor, self).__init__()
self.queue = queue
self.idx = idx
self.kwargs = kwargs
def run(self):
"""Build some CPU-intensive tasks to run via multiprocessing here."""
hash(self.kwargs) # Shameless usage of CPU for no gain...
## Return some information back through multiprocessing.Queue
## NOTE: self.name is an attribute of multiprocessing.Process
self.queue.put("Process idx={0} is called '{1}'".format(self.idx, self.name))
if __name__ == "__main__":
NUMBER_OF_PROCESSES = 5
## Create a list to hold running Processor object instances...
processes = list()
q = Queue() # Build a single queue to send to all process objects...
for i in range(0, NUMBER_OF_PROCESSES):
p=Processor(queue=q, idx=i)
p.start()
processes.append(p)
# Incorporating ideas from this answer, below...
# https://stackoverflow.com/a/42137966/667301
[proc.join() for proc in processes]
while not q.empty():
print "RESULT: {0}".format(q.get()) # get results from the queue...
_
私のマシンでは、これは...
_$ python test.py
RESULT: Process idx=0 is called 'Processor-1'
RESULT: Process idx=4 is called 'Processor-5'
RESULT: Process idx=3 is called 'Processor-4'
RESULT: Process idx=1 is called 'Processor-2'
RESULT: Process idx=2 is called 'Processor-3'
$
_
multiprocessing.Pool
_の使用:FWIW、私が_multiprocessing.Process
_をサブクラス化するときに私が見つけた1つの欠点は、_multiprocessing.Pool
_の組み込みの利点をすべて活用できないことです。 Pool
は、プロデューサーとコンシューマーのコードがキューを介して互いに通信する必要がない必要がない場合に、非常に優れたAPIを提供します。
いくつかの創造的な戻り値だけで多くのことができます...次の例では、dict()
を使用して、pool_job()
からの入力値と出力値をカプセル化しています...
_from multiprocessing import Pool
def pool_job(input_val=0):
# FYI, multiprocessing.Pool can't guarantee that it keeps inputs ordered correctly
# dict format is {input: output}...
return {'pool_job(input_val={0})'.format(input_val): int(input_val)*12}
pool = Pool(5) # Use 5 multiprocessing processes to handle jobs...
results = pool.map(pool_job, xrange(0, 12)) # map xrange(0, 12) into pool_job()
print results
_
これは次の結果になります:
_[
{'pool_job(input_val=0)': 0},
{'pool_job(input_val=1)': 12},
{'pool_job(input_val=2)': 24},
{'pool_job(input_val=3)': 36},
{'pool_job(input_val=4)': 48},
{'pool_job(input_val=5)': 60},
{'pool_job(input_val=6)': 72},
{'pool_job(input_val=7)': 84},
{'pool_job(input_val=8)': 96},
{'pool_job(input_val=9)': 108},
{'pool_job(input_val=10)': 120},
{'pool_job(input_val=11)': 132}
]
_
明らかに、エラー処理など、pool_job()
で行われる他の多くの改善点がありますが、これは本質を示しています。参考までに、 この答え は、_multiprocessing.Pool
_の使用方法の別の例を提供します。
どうもありがとうございました。
今私はそれをどのようにして成し遂げたのかを告げる:)
この例では、各プロセス間ではなく親プロセスとのみ通信する必要がないため、複数のキューを使用しています。
from multiprocessing import Process,Queue
class Processor(Process):
def __init__(self,queue):
Process.__init__(self)
self.que=queue
def get_name(self):
return "Process %s" % self.name
def run(self):
self.que.put(self.get_name())
if __name__ == "__main__":
processes = []
for i in range(0,5):
p=Processor(Queue())
processes.append(p)
p.start()
for p in processes:
p.join()
print p.que.get()
Process.run
の戻り値はどこにも行きません。それらを親プロセスに送り返す必要があります。 multiprocessing.Queue
( ドキュメントはこちら )を使用します。
マイクの答え が最善ですが、完全を期すために、私は好みを述べたいと思いますjoin
contextsからキューを収集するしたがって、最後のビットは次のようになりますこの:
[proc.join() for proc in processes] # 1. join
while not q.empty(): # 2. get the results
print "RESULT: %s" % q.get()