【问题标题】:Multi Threading python 3.7多线程 python 3.7
【发布时间】:2022-01-17 03:29:21
【问题描述】:

我正在尝试根据我提供的 IP 列表优化连接到某些路由器的脚本。

但是,一旦完成前一个路由器,开始配置一次,完成配置需要很长时间,我的问题是,是否可以创建一个不需要等待的函数,也许是多线程功能,可以同时配置几个元素。

def configure_routers():

    hosts = create_vrdc_dic()  # -> it's the dictonary that pass the variables

    for i in hosts .keys():
        hostname = hosts [i].get('hostname')
        mgmt_ip = hosts [i].get('mgmt_ip')

        console_config.config_vrdc(hostname, mgmt_ip)  # -> here I'm calling another module that configures the routers using pexpect

感谢您的帮助。

【问题讨论】:

  • 您是如何处理这些故障的?如果您只是将它们打印到屏幕上,则消息可能是交错的。如果存在阻塞读取,它可能会永远留在那里。
  • 嗨,不,我不只是打印它。基本上,我收到IP,调用另一个python模块来连接和配置路由器,所以我的想法是同时配置2个或3个,所以我不需要配置等待它完成,然后去第二个元素等

标签: python python-3.x


【解决方案1】:

您可能想要使用多处理模块:

##################################################

# Glue functions to get the original function running

import time

def create_vrdc_dic():
    return {
        'host1': { 'hostname': 'host1', 'mgmt_ip': '10.0.0.1' },
        'host2': { 'hostname': 'host2', 'mgmt_ip': '10.0.0.2' },
        'host3': { 'hostname': 'host3', 'mgmt_ip': '10.0.0.3' },
        'host4': { 'hostname': 'host4', 'mgmt_ip': '10.0.0.4' },
        'host5': { 'hostname': 'host5', 'mgmt_ip': '10.0.0.5' } }

class ConsoleConfig:

    def config_vrdc(self, hostname, mgmt_ip):
        print("Configure [%s] [%s]" % (hostname, mgmt_ip))
        time.sleep(10)
        print("Finished configuration [%s] [%s]" % (hostname, mgmt_ip))

console_config = ConsoleConfig()
        
##################################################

from multiprocessing import Process

def configure_routers():

    hosts = create_vrdc_dic()  # -> it's the dictonary that pass the variables

    processes = []
    
    for i in hosts .keys():
        hostname = hosts [i].get('hostname')
        mgmt_ip = hosts [i].get('mgmt_ip')

        p = Process(target=console_config.config_vrdc, args=(hostname, mgmt_ip))
        p.start()
        processes.append(p)

    for p in processes:
        p.join()


##################################################

configure_routers()

可能的输出:

Configure [host1] [10.0.0.1]
Configure [host2] [10.0.0.2]
Configure [host3] [10.0.0.3]
Configure [host4] [10.0.0.4]
Configure [host5] [10.0.0.5]
Finished configuration [host1] [10.0.0.1]
Finished configuration [host2] [10.0.0.2]
Finished configuration [host5] [10.0.0.5]
Finished configuration [host4] [10.0.0.4]
Finished configuration [host3] [10.0.0.3]

运行时间:~10 秒

【讨论】:

    【解决方案2】:

    要同时配置您的路由器,您首先需要确保使用您正在使用的模块/库这样做是安全的。如果一次只应运行一个实例,则只需等待每个路由器都被一一配置。例如,如果您正在使用的进程在运行时读取/写入同一文件/数据库,并且您对该进程进行多线程处理,则最终可能会导致文件/数据库损坏。

    如果您确定您的操作 对多线程是安全的,请尝试以下代码:

    import threading
    
    
    # Create a class for multi-threading the configuration of a router
    class RouterConfigure(threading.Thread):
        def __init__(self, ip: str, hostname: str):
            threading.Thread.__init__(self)
            self.ip = ip
            self.hostname = hostname
    
        def run(self):
            console_config.config_vrdc(self.hostname, self.ip)
    
    
    threads = []
    hosts = create_vrdc_dic()
    
    # Create a thread for each IP/hostname in the dict
    for i in hosts.keys():
        hostname = hosts[i].get('hostname')
        ip = hosts[i].get('mgmt_ip')
        
        thread = RouterConfigure(ip=ip, hostname=hostname)
        thread.start()
        threads.append(thread)
    
    # Wait for threads to finish before exiting main program
    for t in threads:
        t.join()
    

    如果要配置的主机多于您的系统可以通过多个线程处理的数量,请弄清楚如何将进程拆分为多个块,以便只有 x 线程同时运行。

    【讨论】:

    • 太棒了!工作得很好!现在,我正在尝试根据您的代码设置一些限制,不知道是否可能。
    • @bgrbr2016 也许修改它,以便每个RouterConfigure 实例处理一个固定大小的单独字典。请参阅this answer 了解如何将您的 dict 拆分为更小的块。
    【解决方案3】:

    试试这个代码,请根据需要进行必要的修改。

    import thread
    
    def Configure (hostname, mgmt_ip):
        
        console_config.config_vrdc(hostname, mgmt_ip)
    
    
    try :
        def configure_routers():
    
            hosts = create_vrdc_dic()  # -> it's the dictonary that pass the variables
    
            for i in hosts .keys():
                hostname = hosts [i].get('hostname')
                mgmt_ip = hosts [i].get('mgmt_ip')
    
                thread.start_new_thread( Configure, (hostname, mgmt_ip) )
    
        configure_routers()
    except :
        print("The operation cannot be performed")
    

    【讨论】:

    • 您可能需要更正缩进错误
    • 感谢回复我已更正。
    • 嗨,我忘了说它是 python 3.7,显然线程已被弃用。另一个解决方案有效。非常感谢您花时间回答问题,非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2023-03-10
    • 2017-03-22
    • 2018-06-26
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多