не может распараллеливать (потоки) telnet-соединения с python

У меня есть код, который будет подключаться к нескольким маршрутизаторам, используя telentlib, запускать в них некоторый код и, наконец, записывать вывод в файл. Он работает гладко.

Однако, когда мне приходилось обращаться к множеству маршрутизаторов (+50), задача занимает много времени (код запускается последовательно, по одному маршрутизатору за раз). Тогда я подумал об осуществлении потоков, чтобы ускорить процесс.

Это в значительной степени код (просто его фрагмент):

# We import the expect library for python import telnetlib import sys import csv import time import threading # --- Timers TimeLogin = 10 TelnetWriteTimeout = 1 TelnetReadTimeout = 2 # --- CSV FileCsv = "/home/lucas/Documents/script/file.csv" # --- Extras cr="\n" # variables IP = "ABCD" User = ["user","password"] CliLogin = "telnet " + IP Prompt = ["root@host.*]#"] PromptLogin = ["login:"] PromptLogout = ["logout"] PromptPass = ["Password:"] CliLine = "ls -l" class MiThread(threading.Thread): def __init__(self,num,datos): threading.Thread.__init__(self) self.num = num self.datos = datos self.systemIP = self.datos[0] self.tn = telnetlib.Telnet(IP) self.tn.timeout = TimeLogin # File declaration self.FileOutGen = self.systemIP + "_commands" self.FileOutSend = self.systemIP + "_output" self.FileOutRx = self.systemIP + "_rx" self.fg = open(self.FileOutGen,"w") self.fr = open(self.FileOutRx,"a") self.fs = open(self.FileOutSend,"w") def run(self): print "Soy el hilo", self.num self.telnetLogin() self.runLs() self.telnetLogout() def telnetLogin(self): i=self.tn.expect(PromptLogin) print i if i: writeTelnet(User[0],TelnetWriteTimeout) j=self.tn.expect(PromptPass) print j if j: writeTelnet(User[1],TelnetWriteTimeout) def telnetLogout(self): i=self.tn.expect(Prompt) if i: writeTelnet("exit",TelnetWriteTimeout) j=self.tn.expect(PromptLogout) if j: print "Logged out OK from SAM" def runLs(self): writeLog("Prueba de Ls " + self.systemIP) self.writeCsv(self.systemIP,1) i=self.tn.expect(Prompt,TimeLogin) print i if i: # Prompt CliLine = "ls -l " writeTelnet(CliLine,TelnetWriteTimeout) def writeCsv(self,inText,lastIn): lock.acquire(1) if lastIn==0: fc.write(inText + ",") elif lastIn==1: fc.write(inText + "\n") lock.release() def writeTelnet(inText, timer): tn.write(inText + cr) time.sleep(timer) def writeLog(inText): print (inText) t.fs.write("\n" + inText) def printConsole(inText): print (inText) oFile = csv.reader(open(FileCsv,"r"), delimiter=",", quotechar="|") lock = threading.Lock() routers = list(oFile) threads_list = [] for i in range(len(routers)): FileOutCsv = "00_log.csv" # creating output file fc = open(FileOutCsv,"a") # running routine t = MiThread(i,routers[i]) threads_list.append(t) t.start() 

… все работает хорошо, но вовремя нет выигрыша, так как t.join () заставит поток завершить работу перед запуском следующего!

Факт сериализации потоков (что означает использование t.join ()) заставляет меня думать, что некоторые пространства памяти разделяются, потому что проблема возникает, когда я хочу распараллелить их (комментируя t.join ()).

Что-то не так, что я делаю? Я могу предоставить дополнительную информацию, если это необходимо, но я действительно не знаю, что я делаю неправильно до сих пор …

3 Solutions collect form web for “не может распараллеливать (потоки) telnet-соединения с python”

Поэтому после некоторого рытья ошибка была найдена.

Раньше функция writeTelnet () была объявлена ​​вне класса. После того, как он переместился внутри него и надлежащим образом ссылался на остальные (то есть: self.writeTelnet ()), все работало настолько, насколько это ожидалось.

Вот фрагмент нового кода:

 class MiThread(threading.Thread): def __init__(self,num,datos): threading.Thread.__init__(self) self.num = num self.datos = datos self.systemIP = self.datos[0] self.tn = telnetlib.Telnet(IP) self.tn.timeout = TimeLogin # File declaration self.FileOutGen = self.systemIP + "_commands" self.FileOutSend = self.systemIP + "_output" self.FileOutRx = self.systemIP + "_rx" self.fg = open(self.FileOutGen,"w") self.fr = open(self.FileOutRx,"a") self.fs = open(self.FileOutSend,"w") [ . . . ] def writeTelnet(self,inText, timer): self.tn.write(inText + ch_cr) time.sleep(timer) oFile = csv.reader(open(FileCsv,"r"), delimiter=",", quotechar="|") routers = list(oFile) for i in range(len(routers)): # creating output file fc = open(FileOutCsv,"a") # running routine t = MiThread(i,routers[i]) t.start() 

И теперь ясно (по крайней мере, для меня): поскольку в какой-то момент разные потоки нуждаются в записи в их telnet-соединение, им нужно однозначно идентифицировать его. Единственный способ, которым я нашел это, – включить функцию внутри класса.

Спасибо вам всем,

Лукас

Из прошлого опыта вам нужно запустить все потоки и присоединиться к ним после того, как они все начались.

 thread_list = [] for i in range(routers): t = MiThread(i, routers[i]) threadlist.append(t) t.start() for i in thread_list: i.join() 

Это запустит каждый поток, а затем дождитесь завершения всех потоков, прежде чем двигаться дальше.

Я думаю, вы можете их собрать. что-то вроде ниже. (не пробовал)

 count=20 start=1 for i in range(len(routers)): if start == count : for _myth in range(1,i+1): thread_list[_myth].join() start+=1 FileOutCsv = "00_log.csv" # creating output file fc = open(FileOutCsv,"a") # running routine t = MiThread(i,routers[i]) threads_list.append(t) t.start() start+=1 
    Python - лучший язык программирования в мире.