0

我使用netmiko进行网络自动化的简单代码如下:所以首先我有:

  1. 函数 cisco_command 用于从输入文件中读取命令
  2. 函数 cisco_host 用于从输入文件中读取主机信息
  3. 函数 open_connection 用于启动与设备的连接
  4. 用于多处理的函数 run_program
  5. 函数 main 是主程序

所以我的代码有问题,你可以在 open_connection func 上看到我们有全局变量 commands_info 但是如果我们通过多处理 (run_program func) 运行这个程序,则 open_connection func 无法读取全局变量。

import time
import os
import concurrent.futures
from netmiko import ConnectHandler
from functools import partial


full_path = os.path.dirname(__file__)
host_file = os.path.join(full_path, "lab-router.txt")
command_file = os.path.join(full_path, "cisco-log.txt")
starting_time = ""


command_info = []

def cisco_command():
    global command_info
    command_info = []
    with open(command_file, 'r') as commands:
        for line in commands:
            com = line.strip()
            command_info.append(com)
    return command_info
    
def cisco_host():
    global starting_time
    hosts_info = []
    with open(host_file, 'r') as devices:
        for line in devices:
            deviceip = line.strip()
            host = {
                'device_type': 'cisco_ios',
                'ip': deviceip,
                'username': 'dodo',
                'password': 'dodo',
                'secret': 'dodo'
            }
            hosts_info.append(host)

    starting_time = time.perf_counter()
    return hosts_info

def open_connection(host):
    global command_info
    sendcommand = ""     
    try:
        connection = ConnectHandler(**host)
        print('Connection Established to Host:', host['ip'])
        connection.enable()
        for i in command_info:
            sendcommand += "\n"
            sendcommand += "==== {} ====".format(i)
            sendcommand += "\n"
            sendcommand += connection.send_command(i)
            sendcommand += "\n"
# return sendcommand
        with open("{}/{}_log.txt".format(full_path, host['ip']), 'w') as nf:
            nf.write(sendcommand)  
    except:
        print('Connection Failed to host', host['ip'])
    

        
def run_program(hosts_info):
    with concurrent.futures.ProcessPoolExecutor() as executor:
        results = executor.map(open_connection, hosts_info)
            
        for result in results:
            pass

        finish = time.perf_counter()
        print('Time Elapsed:', finish - starting_time)
    
def main():
    commads = cisco_command()
    hosts_info = cisco_host()
    run_program(hosts_info)


    
if __name__ == '__main__':
    main()

我不知道我错了什么

4

1 回答 1

0

你写了:

如果我们通过多处理(run_program func)运行该程序,则 open_connection func 无法读取全局变量。

这种说法实际上是不正确的。您的全局变量command_info确实由函数读取open_connection。这不是问题。

我看到您遇到的问题是您正在尝试使用该命令来允许您将运行该函数的每个 cpu 核心处理global的更改更新到主核心中的全局。这行不通。想象一下,您有 4 个 cpu 同时运行,每个 cpu 都试图同时修改同一个全局术语。如果 Python 允许它不允许的东西,那将是一场噩梦。command_infoopen_connectioncommand_info

实际上,Python 允许您传递command_info到每个 CPU 核心(不使用全局),您command_info现在可以将其视为该计算核心独有的全局变量。要将command_info每个唯一核心的更新传递回正在运行的主核心,您必须在函数结束时concurrent.futures.ProcessPoolExecutor()返回(连同您的)。然后在主核心中,您可以将其作为. 此后,您可以更新主核心中的全局变量。command_infoopen_connection(host)sendcommandresultresultscommand_info

希望这个解释可以帮助您理解您的问题。:)

于 2021-07-02T10:37:44.720 回答