下面的Python代码连接到许多服务器,从每个服务器获取一些信息并返回结果。它目前为每个连接启动一个单独的线程。我想看看如何通过为每个连接使用单独的进程而不是线程来影响性能。可以轻松地将此代码更改为使用进程而不是线程吗?我究竟需要做什么?有什么风险?
Python 2.6 / Platform Linux
class ServerInfoGetter(threading.Thread):
def __init__(self, host, port=DEFAULT_PORT, timeout=15):
self.host = host
self.timeout = timeout
self.port = port
self.result = None
threading.Thread.__init__(self)
def get_result(self):
return self.result
def run(self):
try:
serv_check = ServCheck(self.host, \
port=self.port, \
timeout=self.timeout)
serv_check.get_info()
self.result = serv_check
except Exception, err:
logging.debug("Could not run ServCheck for : %s %s",self.host, err)
def process_hosts(hosts_and_ports):
def producer(queue, hosts_and_ports):
for host, ports in hosts_and_ports.items():
for port in ports:
logging.info("processing host: %s:%s", host, port)
thread = ServerInfoGetter(str(host), port)
thread.start()
queue.put(thread, True) # True so block until slot available
results = []
def consumer(queue, total_checks):
while len(results) < total_checks:
thread = queue.get(True)
thread.join()
results.append(thread.get_result())
logging.info("processing hosts")
queue = Queue(QUEUE_SIZE)
prod_thread = threading.Thread(target=producer,
args=(queue,
hosts_and_ports))
cons_thread = threading.Thread(target=consumer,
args=(queue,
calculate_total_checks(hosts_and_ports)))
prod_thread.start()
cons_thread.start()
prod_thread.join()
cons_thread.join()
return results
答案 0 :(得分:3)
您是否考虑过使用单个流程和单个线程,例如使用twisted? 当os.fork可用时,多进程选项可能相当容易....
答案 1 :(得分:3)
正如documentation中所述:
multiprocessing
是一个使用类似于threading
模块的API支持产生进程的包。 [...]在multiprocessing
中,通过创建Process
对象然后调用其start()
方法来生成进程。流程遵循threading.Thread
的API。
所以,基本上,你只需要用threading.Thread
个对象替换所有multiprocessing.Process
个对象(类似地,队列需要用multiprocessing.Queue
个对象替换。)
至少,这就是它的表现。但是,实际上,需要跨越Process
边界的所有对象都需要是multiprocessing.Value
个对象。否则,它们永远不会跨线程更新。
如果您只修改self.host
课程,则其中包括self.timeout
,self.port
,self.result
,ServerInfoGetter
。阅读多处理文档的其余部分,以了解您需要使用的其他数据类型。
另外,作为旁注,我不确定它对Linux上的python 2.6是否有问题,但是对于Windows上的python 2.7,无论是空闲还是交互式解释器都有麻烦(对我来说,至少)多处理。使用python或pythonw可执行文件直接执行脚本时,这些问题就消失了。 更新 - 我的Slackware盒子上的python 2.5.1没有这个问题,所以你可能在交互模式下也没问题......虽然winwaed不是,所以谁知道......?