我正在使用Python和Netmiko通过ssh连接在我的网络基础结构中进行爬网。不幸的是,除非您拥有自己的类似网络基础结构,否则代码将无法执行。
我的问题更多是关于python中的多线程理论。
这是我想要实现的算法:
连接到我的核心交换机。 收集邻居信息。 断开连接
在列表中放置邻居。 浏览列表: 连接到每个邻居 收集邻居信息。 断开 将新邻居放在同一列表中。
这是主要的问题循环:
#ssh to all equipements in neighbors detecteid, gather info+ update neighbors list. Multithread to be much faster
#cannot be more than 6 waves of uplink
for i in range(6):
#browse switch name in the list
for a_device in switch_list[3::3]:
#if the neighbor was not already analyzed
if not switch_list[switch_list.index(a_device)+2]:
print('connection to...' + a_device)
#multithread all neighbors to be analyzed and update list
threads.append(threading.Thread(target=ssh_and_gather, args=(a_device,location,switch_list)))
for x in threads:
x.start()
for x in threads:
x.join()
它失败并显示以下错误:
Traceback (most recent call last):
File "ansible_switch_discover.py", line 130, in <module>
main()
File "ansible_switch_discover.py", line 114, in main
x.start()
File "/usr/lib64/python2.7/threading.py", line 741, in start
raise RuntimeError("threads can only be started once")
我该如何修复我的代码,使其继续向多线程添加线程(到新发现的邻居的ssh连接)?
我只尝试过一次start(),但是错误是:
Traceback (most recent call last):
File "ansible_switch_discover.py", line 132, in <module>
main()
File "ansible_switch_discover.py", line 119, in main
x.join()
File "/usr/lib64/python2.7/threading.py", line 940, in join
raise RuntimeError("cannot join thread before it is started")
谢谢
答案 0 :(得分:0)
请注意了解我的语言:
范围循环:for i in range(6):
启动循环:
for x in threads:
x.start()
加入循环:
for x in threads:
x.join()
问题是您试图多次启动同一线程:
for i in range(6):
for a_device in switch_list[3::3]:
if not switch_list[switch_list.index(a_device)+2]:
print('connection to...' + a_device)
threads.append(threading.Thread(target=ssh_and_gather, args=(a_device,location,switch_list)))
for x in threads:
x.start()
for x in threads:
x.join()
列表线程包含多个线程(属于同一线程),这是您所需要的,但不是正确的方法。
start和join循环的位置不正确,您可以解决将其放置在这样的情况(在range循环之外):
threads = list()
for i in range(6):
for a_device in switch_list[3::3]:
if not switch_list[switch_list.index(a_device)+2]:
print('connection to...' + a_device)
threads.append(threading.Thread(target=ssh_and_gather, args=(a_device,location,switch_list)))
for x in threads:
x.start()
for x in threads:
x.join()
现在在此代码中,首先创建所有线程,然后启动并加入它,因此不会出现任何错误,因为您不会多次启动同一线程。
执行此操作的另一种方法是保留代码,并在启动和加入循环之后清除线程列表,因此该线程仅启动一次。
尝试解释:
这是第一个范围循环之后的线程列表:
threads = [th1, th2, th3, th4, th5, th6]
现在所有这些线程都根据您的代码启动并加入了。 在第二个循环中,将更多线程附加到列表中:
threads = [th1, th2, th3, th4, th5, th6, th1, th2, th3, th4, th5, th6]
现在,您开始并再次连接线程,但是,您在列表的位置0开始th1,当您在列表的位置6到达th1时,它会引发错误,因为是相同的对象th1(因此您多次启动同一线程)。
因此,要解决该问题,可以将启动和联接列表保留在代码位置,并在启动和联接后添加线程删除,或者可以将范围和循环移出启动和联接循环。