也许更熟悉Python的多处理池代码的人可以帮助我。我试图通过套接字连接同时连接到我的网络上的几个主机(任何时候N)并执行一些RPC。当一个主机完成时,我想将下一个主机添加到池中,直到所有主机都完成为止。
我有一个类,HClass,有一些方法可以这样做,还有一个主机列表中包含的主机名列表。但我没有找到任何一个docs.python.org的例子来使这个工作。
一段简短的代码片段,用以说明我到目前为止所获得的内容:
hostlist = [h1, h2, h3, h4, ....]
poolsize = 2
class HClass:
def __init__(self, hostname="default"):
self.hostname = hostname
def go(self):
# do stuff
# do more stuff
....
if __name__ == "__main__":
objs = [HClass(hostname=current_host) for current_host in hostlist]
pool = multiprocessing.pool(poolsize)
results = pool.apply_async(objs.go())
到目前为止,我很幸运有这个追溯:
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 551, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 504, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/lib/python2.7/multiprocessing/pool.py", line 319, in _handle_tasks
put(task)
PicklingError: Can't pickle <type 'generator'>: attribute lookup __builtin__.generator failed
这个过程只是挂起,直到我把Control-C拿出来。
答案 0 :(得分:6)
我会尽量将进程间通信保持在最低限度。看起来您真正需要发送的是主机名字符串:
for host in hostlist:
pool.apply_async(worker, args = (host,), callback = on_return)
例如,
import multiprocessing as mp
import time
import logging
logger = mp.log_to_stderr(logging.INFO)
hostlist = ['h1', 'h2', 'h3', 'h4']*3
poolsize = 2
class HClass:
def __init__(self, hostname="default"):
self.hostname = hostname
def go(self):
logger.info('processing {h}'.format(h = self.hostname))
time.sleep(1)
return self.hostname
def worker(host):
h = HClass(hostname = host)
return h.go()
result = []
def on_return(retval):
result.append(retval)
if __name__ == "__main__":
pool = mp.Pool(poolsize)
for host in hostlist:
pool.apply_async(worker, args = (host,), callback = on_return)
pool.close()
pool.join()
logger.info(result)
答案 1 :(得分:1)
我认为这与Can't pickle <type 'instancemethod'> when using python's multiprocessing Pool.map()
是同一个问题从上面链接中的答案中复制。问题是多处理必须腌制东西以在进程之间吊索它们,并且绑定方法不可选。
一种方法是使go功能无限制,就像把它放在课外一样。或者使用copy_reg
打包该功能答案 2 :(得分:1)
我同意@ unutbu的解决方案......更简单更好。但是,如果您必须发送类方法go
,我将使用pathos.multiprocesssing
,而不是multiprocessing
。
>>> from pathos.multiprocessing import ProcessingPool as Pool
>>> p = Pool(4)
>>> class Test(object):
... def plus(self, x, y):
... return x+y
...
>>> t = Test()
>>> p.map(t.plus, x, y)
[4, 6, 8, 10]