我正在尝试向XMLRPC服务器(mosesserver)发送多个并行请求。要启动XMLRPC调用,需要ServerProxy对象(此对象包含服务器的URL,以及其他内容)
在串行执行中,我可以在程序开头创建此对象(调用xmlrpclib.ServerProxy(server_URL)),将其存储在变量中,并在需要时使用它。
但是当使用进程池时,每个进程都需要该对象的不同实例。每个过程的任务是从输入中读取一行并通过XMLRPC将其发送到翻译服务器,等待结果,获取另一行,再次发送...
每次进程调用XMLRPC时,每个进程都很容易创建一个新的ServerProxy实例,但问题是第一次调用比使用相同ServerProxy对象的后续调用花费的时间更长。所以我想要做的是每个进程在第一次进行RPC调用时创建一个ServerProxy对象,然后它为后面的调用重用相同的ServerProxy对象(在串行执行中完成它的方式)。但是我存在存储该对象的问题。
import xmlrpclib
import sys
import os
import multiprocessing
import time
def func(dummy_argument,que):
server = xmlrpclib.ServerProxy('http://myserver:6060/RPC2',)
# server="HELLO"
que.put(server)
return
def run_parallel(line,num_procesos):
pool = multiprocessing.Pool(processes=num_procesos)
m = multiprocessing.Manager()
q = m.Queue()
for i in range (0, num_procesos):
pool.apply_async(func, ("dummy",q))
while not q.empty():
print q.get()
pool.close()
pool.join()
return
if __name__ == '__main__':
line="test"
run_parallel(line,4)
在上面的代码中,如果我取消注释'server =“HELLO”',一切似乎工作正常,但当我删除该行,所以ServerProxy对象'服务器'必须入队,我收到以下错误:
Exception in thread Thread-3:
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 353, in _handle_results
task = get()
TypeError: ('__init__() takes exactly 3 arguments (1 given)', <class 'xmlrpclib.Fault'>, ())
它引用的 init 方法是ApplyResult类的构造函数(类
其实例由Pool.apply_async()
)
事实是,即使我能够正确存储和检索此对象,我也不确定我是否能按照我的意图使用它,但至少我想尝试一下。
任何人都知道问题出在哪里?
或许还有另一种(可能更简单的)方法来做我需要的事情吗?
由于
答案 0 :(得分:2)
如果我理解,你的问题是如何在每个子流程中只初始化一次代理。您可以利用initializer
的{{1}}参数,以及每个进程都有自己的全局变量的事实:
multiprocessing.Pool()
我还展示了在那里处理import xmlrpclib
import multiprocessing
def init():
global server
server = xmlrpclib.ServerProxy('http://myserver:6060/RPC2',)
def func(argument):
result = server.some_function(argument)
return result
def run_parallel(line,num_procesos):
pool = multiprocessing.Pool(processes=num_procesos, initializer=init)
async_results = [pool.apply_async(func, ("dummy",q))
for i in range (0, num_procesos)]
for r in async_results:
print r.get()
pool.close()
pool.join()
if __name__ == '__main__':
line="test"
run_parallel(line,4)
结果的典型方法。