问题描述
我有使用 netmiko 进行网络自动化的简单代码: 所以首先我有:
- 函数 cisco_command 从输入文件读取命令
- 函数 cisco_host 从输入文件中读取主机信息
- 函数 open_connection 用于启动与设备的连接
- 用于多处理的函数 run_program
- function 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()
我不知道我错了什么
解决方法
你写道:
如果我们通过多处理(run_program func)运行这个程序 open_connection func 无法读取全局变量。
这个说法其实是错误的。您的全局变量 command_info
确实由函数 open_connection
读取。这不是问题。
我看到您遇到的问题是您正在尝试使用命令 global
来更新 command_info
中由运行 open_connection
的每个 CPU 内核处理的更改函数到主内核中的全局 command_info
。这行不通。想象一下,您有 4 个 cpu 同时运行,每个 cpu 都试图同时修改同一个全局术语。如果 Python 允许它不允许的东西,那将是一场噩梦。
实际上,Python 允许您将 command_info
传递到每个 CPU 内核(不使用全局),您现在可以将 command_info
视为该计算内核独有的全局变量。要将每个唯一内核的更新后的 command_info
传递回运行 concurrent.futures.ProcessPoolExecutor()
的主内核,您必须在函数 command_info
的末尾返回 open_connection(host)
(以及你的sendcommand
)。然后在主核心中,您可以将其作为 result
of results
中的术语之一访问。此后,您可以更新主内核中的全局 command_info
变量。
希望此说明能帮助您了解您的问题。 :)