Python 多处理,pool.ready做什么?
假设我有一个池,在一个类中有几个进程,我用它来做一些处理,如下所示:Python 多处理,pool.ready做什么?,python,multiprocessing,pool,Python,Multiprocessing,Pool,假设我有一个池,在一个类中有几个进程,我用它来做一些处理,如下所示: class MyClass: def __init_(self): self.pool = Pool(processes = NUM_PROCESSES) self.pop = [] self.finished = [] def gen_pop(self): self.pop = [ self.pool.apply_async(Item.tes
class MyClass:
def __init_(self):
self.pool = Pool(processes = NUM_PROCESSES)
self.pop = []
self.finished = []
def gen_pop(self):
self.pop = [ self.pool.apply_async(Item.test, (Item(),)) for _ in range(NUM_PROCESSES) ]
while (not self.check()):
continue
# Do some other stuff
def check(self):
self.finished = filter(lambda t: self.pop[t].ready(), range(NUM_PROCESSES))
new_pop = []
for f in self.finished:
new_pop.append(self.pop[f].get(timeout = 1))
self.pop[f] = None
# Do some other stuff
当我运行这段代码时,我会得到一个cPickle.PicklingError
,它表明
不能被pickle。这告诉我一个apply\u async
函数尚未返回,因此我试图将一个正在运行的函数附加到另一个列表中。但这不应该发生,因为所有正在运行的调用都应该使用ready()
函数过滤掉
与此相关的一点是,项
类的实际性质并不重要,但重要的是在我的项的顶部。test
函数中有一个print语句,该语句应该用于调试目的。然而,这并没有发生。这告诉我函数已经启动,但实际上还没有开始执行
因此,看来
ready()
实际上并没有告诉我调用是否已完成执行。ready()
具体做什么?我应该如何编辑我的代码,以便过滤掉仍在运行的进程?多处理在内部使用pickle
模块在进程之间传递数据,
因此,您的数据必须是可拾取的。请参见,对象方法不在该列表中。要快速解决此问题,只需在方法周围使用包装函数:
def wrap_item_test(item):
item.test()
class MyClass:
def gen_pop(self):
self.pop = [ self.pool.apply_async(wrap_item_test, (Item(),)) for _ in range(NUM_PROCESSES) ]
while (not self.check()):
continue
为了回答您提出的问题,
.ready()
确实在告诉您.get()
是否可以阻止:如果.ready()
返回True
,.get()
不会阻止,但是如果.ready()
返回False
,.get()
可以阻止(也可能不是:很可能异步调用将在您开始调用.get()
之前完成)
因此,例如,.get()
中的timeout=1
没有任何作用:因为如果.ready()
返回True
,则只调用.get()
,您已经知道.get()
不会阻塞
但是.get()
不阻塞并不意味着异步调用成功,甚至工作进程甚至开始处理异步调用:正如文档所说
如果远程调用引发异常,则将通过get()
重新调用该异常
也就是说,例如,如果根本无法执行异步调用,.ready()
将返回True
,.get()
将(重新)引发阻止尝试工作的异常
这似乎就是您的情况,尽管我们不得不猜测,因为您没有发布可运行代码,也没有包含回溯
请注意,如果您真正想知道的是,在从.ready()
返回True
后,异步调用是否正常完成,那么.successful()
就是要调用的方法
很明显,无论
Item.test
可能是什么,由于pickle限制,根本不可能将其作为可调用的.apply\u async()
传递。这就解释了为什么Item.test
从不打印任何内容(实际上从未调用过!),为什么.ready()
返回True
(the.apply\u async()
调用失败),以及为什么.get()
引发异常(因为.apply\u async()
在尝试pickle其一个参数时遇到异常-可能是项。test
).你为什么认为cPickle.PicklingError
就是这个意思?@zwol我真的不这么认为。相反,我认为这个错误是实际问题的一个症状,这在我的问题中有详细说明。我想说的是,我认为你对实际问题的诊断是错误的。那么,我能把包装项目测试
放在包含项的e模块
?或者我还需要知道什么?