Skip to main content
 首页 » 编程设计

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

2025年05月04日35sxdcgaq8080

下面的 Python 代码连接到许多服务器,从每个服务器获取一些信息并返回结果。它目前为每个连接启动一个单独的线程。我想看看对每个连接使用单独的进程而不是线程对性能有何影响。是否可以轻松更改此代码以使用进程而不是线程?我到底需要做什么?有什么风险,如果有的话?

Python 2.6/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 

请您参考如下方法:

正如它在 documentation 中所说的那样:

multiprocessing is a package that supports spawning processes using an API similar to the threading module. [...] In multiprocessing, processes are spawned by creating a Process object and then calling its start() method. Process follows the API of threading.Thread.

因此,基本上,您只需将所有 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 box 上的 python 2.5.1 没有这个问题,所以你在交互模式下可能也很好......虽然 winwaed 不是,所以谁知道......?