考虑以下多处理python程序:
import multiprocessing as mp
from math import sqrt
def funcA(mylist):
worker_poolA = mp.Pool()
jobs = mylist
results = worker_poolA.map(sqrt, jobs)
worker_poolA.close()
worker_poolA.join()
return results
def funcB():
worker_poolB = mp.Pool()
jobs = [[0, 1, 4, 9, 16, 25],[25, 4, 16, 0,1]]
finalresults = worker_poolB.map(funcA, jobs)
worker_poolB.close()
worker_poolB.join()
print finalresults
def funcC():
jobs = [[0, 1, 4, 9, 16, 25],[25, 4, 16, 0,1]]
for job in jobs:
print funcA(job)
if __name__ == "__main__":
funcC() #works fine
funcB() #ERROR: AssertionError: daemonic processes are not allowed to have children
为了解决这个问题,我接着对subproces.pool.Pool模块进行Subclas并将守护进程标志设置为False,如post所示。但现在它导致了僵尸进程的创建。从另一个池函数调用池函数的正确方法是什么?这种设计有缺陷吗?我使用的是python 2.6。
答案 0 :(得分:2)
简单回答:multiprocessing
不允许你这样做,因为它会将内部进程孤立为守护进程,就像错误所说的那样。你可以解决它(我指的是processing
的旧版本,允许这样做,并在我的包pathos
中分叉)。但是,如果你解决它,你必须手动杀死守护进程,所以它真的不值得。
通常情况下,您需要一个嵌套map
的情况,而较低级别的作业是“重”,而较高级别的作业是“轻”......或者类似的东西。一项工作是工作的“肉”,另一项工作只是分配基础工作。对于这种情况,您可以使用两种不同类型的pool
。
例如,线程和进程。我正在使用我的fork(称为multiprocess
),因为它在解释器中更容易使用 - 但在这种特殊情况下与multiprocessing
相同。
>>> import multiprocess as mp
>>> from math import sqrt
>>>
>>> def funcA(mylist):
... worker_poolA = mp.Pool()
... jobs = mylist
... results = worker_poolA.map(sqrt, jobs)
... worker_poolA.close()
... worker_poolA.join()
... return results
...
>>> def funcB():
... worker_poolB = mp.dummy.Pool()
... jobs = [[0, 1, 4, 9, 16, 25],[25, 4, 16, 0,1]]
... finalresults = worker_poolB.map(funcA, jobs)
... worker_poolB.close()
... worker_poolB.join()
... print finalresults
...
>>> def funcC():
... jobs = [[0, 1, 4, 9, 16, 25],[25, 4, 16, 0,1]]
... for job in jobs:
... print funcA(job)
...
>>> funcC()
[0.0, 1.0, 2.0, 3.0, 4.0, 5.0]
[5.0, 2.0, 4.0, 0.0, 1.0]
>>> funcB()
[[0.0, 1.0, 2.0, 3.0, 4.0, 5.0], [5.0, 2.0, 4.0, 0.0, 1.0]]