繁体   English   中英

无法使用python并行化(线程化)telnet连接

[英]cannot parallelize (threads) telnet connections with 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 = "A.B.C.D"
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())时就会出现问题。

我做错什么了吗? 如果需要,我可以提供更多信息,但我真的不知道到目前为止我做错了什么...

因此,在进行一些挖掘之后,发现了错误。

之前,函数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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM