如何将此Python代码更改为多进程而不是多线程?

时间:2011-03-05 21:12:40

标签: python multithreading multiprocessing

下面的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

2 个答案:

答案 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.timeoutself.portself.resultServerInfoGetter。阅读多处理文档的其余部分,以了解您需要使用的其他数据类型。

另外,作为旁注,我不确定它对Linux上的python 2.6是否有问题,但是对于Windows上的python 2.7,无论是空闲还是交互式解释器都有麻烦(对我来说,至少)多处理。使用python或pythonw可执行文件直接执行脚本时,这些问题就消失了。 更新 - 我的Slackware盒子上的python 2.5.1没有这个问题,所以你可能在交互模式下也没问题......虽然winwaed不是,所以谁知道......?

相关问题