如何在python中使用Multiprocess池从不同的类(不同的模块)调用方法?
我的目标是启动一个持续运行的流程,直到提供任务为止,一旦任务完成,它将再次返回等待模式。
下面是代码,其中有三个模块,Reader类是我的运行时任务,我将为ProcessExecutor提供执行读取器方法。 进程执行程序是进程池,它将在循环中继续,直到向其提供某个任务。
主要模块启动一切。
Module 1
class Reader(object):
def __init__(self, message):
self.message = message
def reader(self):
print self.message
Module 2
class ProcessExecutor():
def run(self, queue):
print 'Before while loop'
while True:
print 'Reached Run'
try:
pair = queue.get()
print 'Running process'
print pair
func = pair.get('target')
arguments = pair.get('args', None)
if arguments is None:
func()
else:
func(arguments)
queue.task_done()
except Exception:
print Exception.message
main Module
from process_helper import ProcessExecutor
from reader import Reader
import multiprocessing
import Queue
if __name__=='__main__':
queue = Queue.Queue()
myReader = Reader('Hi')
ps = ProcessExecutor()
pool = multiprocessing.Pool(2)
pool.apply_async(ps.run, args=(queue, ))
param = {'target': myReader.reader}
queue.put(param)
执行的代码没有任何错误:C:\ Python27 \ python.exe C:/Users/PycharmProjects/untitled1/main/main.py
处理完成,退出代码为0
代码被执行但它从未到达run方法。我不确定是否可以使用多进程调用不同类的方法
我尝试了apply_async,map,apply但是没有一个正在运行。 在线搜索的所有示例都是从实现main方法的脚本调用目标方法。 我正在使用python 2.7 请帮忙。
答案 0 :(得分:0)
你的第一个问题是你只需退出而不等任何事情。您有一个Pool
,一个Queue
和一个AsyncResult
,但您只需忽略所有这些内容,并在创建后立即退出。你应该只能等待AsyncResult
(之后,没有更多的工作要做了,所以谁关心你放弃了什么),除了你的事实尝试使用Queue.task_done
,如果没有另一方Queue.join
则没有任何意义,所以你也需要等待。
您的第二个问题是您正在使用Queue
模块中的Queue
,而不是multiprocessing
模块中的Queue
。 task_done
模块仅适用于同一进程中的线程。
此外,您无法在普通Queue
上致电JoinableQueue
;这只是dill
子类的一种方法。
一旦你达到了池试图实际运行任务的程度,你就会遇到绑定方法无法被腌制的问题,除非你为它们编写了一个pickler。这样做很痛苦,尽管这是正确的方法。传统的解决方法 - hacky和俗气,但每个人都这样做,而且它的工作原理是将每个要调用的方法包装在顶级函数中。现代解决方案是使用第三方cloudpickle
或multiprocessing
库,它们知道如何挑选绑定方法,以及如何挂钩from process_helper import ProcessExecutor
from reader import Reader
import multiprocessing
def call_run(ps):
ps.run(queue)
def call_reader(reader):
return reader.reader()
if __name__=='__main__':
queue = multiprocessing.JoinableQueue()
myReader = Reader('Hi')
ps = ProcessExecutor()
pool = multiprocessing.Pool(2)
res = pool.apply_async(call_run, args=(ps,))
param = {'target': call_reader, 'args': myReader}
queue.put(param)
print res.get()
queue.join()
。你一定要看看它们。但是,为了简单起见,我将向您展示解决方法。
请注意,因为您已经创建了一个额外的队列来传递方法,除了池中内置的方法之外,您还需要两个目标的解决方法。
修复了这些问题后,您的代码如下所示:
ProcessReader
您的Pool
还有其他错误,但我不打算为您调试所有内容。这可以让您超越最初的障碍,并显示您询问的具体问题的答案。此外,我不确定所有代码的重点是什么。您似乎试图替换Pool
已经在ProcessExecutor
之上执行的操作,只是以更复杂但功能更弱的方式,但我并不完全确定。
与此同时,这是一个程序,只需丢弃from reader import Reader
import multiprocessing
def call_reader(reader):
return reader.reader()
if __name__=='__main__':
myReader = Reader('Hi')
pool = multiprocessing.Pool(2)
res = pool.apply_async(call_reader, args=(myReader,))
print res.get()
以及随之而来的所有内容,即可完成我认为您想要的,没有问题:
{{1}}