python subclassing multiprocessing.Process
我是新来的python面向对象,我重写我的现有应用程序作为面向对象的版本,因为现在开发人员越来越多,我的代码变得不可维护。python subclassing multiprocessing.Process
通常我使用多队列,但是我从这个例子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
的一个缺点是,您无法充分利用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()
中还有很多其他的改进,比如错误处理,但是这说明了要点。 FYI,this answer提供了另一个如何使用multiprocessing.Pool
的例子。
非常感谢大家。
现在继承人我得到了它做:)
在这个例子中,我使用,因为我不希望每个ohter之间,但只有与父进程通信的多个queus。
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()
请检查我的代码并让我知道我可以改进哪些更pythonic /和更好的实践。 –
你应该使用'super()'...看我的帖子... –
THANKs我会检查。但我读过超级是危险的,尤其是多重继承?真的吗? –
Mike's answer是最好的,但只是为了完整性我想提一提,我更喜欢收获出队列join
上下文所以最后一位应该是这样的:
[proc.join() for proc in processes] # 1. join
while not q.empty(): # 2. get the results
print "RESULT: %s" % q.get()
所以,其中一种方法必须接受Queue对象作为参数吗? –
完成!我创建了一个接受队列的init方法。这反过来扩展了多处理。直接接受队列的进程:) –
感谢您的更正。这段代码返回self.queue.put(self.return_name())'返回一个队列? –