首页 > 解决方案 > 使用 Python 的并行线程/远程登录:不能使用 len(list) > 1000

问题描述

我有一个程序会接收一个包含路由器 IP 地址的列表。对于其中的每一个,将通过 SSH 隧道触发 telnet 连接。

这很好用。除了如果列表大于 1000 个地址(即 1250),则仅考虑前 1000 个元素。前 1000 个可以,但其余 250 个甚至都不会考虑。

所以,首先,伪代码:

  1. 打开与服务器的 ssh 连接并启动 ssh 隧道。返回本地端口
  2. 使用本地端口打开到远程路由器的 telnet 连接
  3. 做一点事
  4. 关闭远程登录
  5. 关闭 ssh

并行连接数是固定整数(10、20、30 等)。我已经用 40 个并行连接测试了代码。

这是代码本身。

import ipaddress as ip
import threading
from multiprocessing.pool import ThreadPool,Pool
import paramiko
from sshtunnel import SSHTunnelForwarder

class connTelnet(threading.Thread):

    def __init__(self,thrdNum, script, loopback):
        threading.Thread.__init__(self)
        self.num            = thrdNum
        self.script         = script
        self.loopback       = loopback
        self.strConn        = "Con-" + str(self.num) + "| "

def run(self):
    self.s = self.sshStart(self.strConn,self.loopback)
    self.sshStatus = self.s[0]
    self.sshServer = self.s[1]
    self.localPort = self.s[2]

    if self.sshStatus == 1:
        print(self.strConn + ": Quitting....")
        self.sshStop(self.sshServer,self.strConn,self.num)

def sshStart(self,strConn,loopback):
    try:
        sshServer = SSHTunnelForwarder(
            (IP, PORT),
            ssh_username = USER,
            ssh_password = PASSWORD,
            remote_bind_address = (loopback, 23),
        )
        sshServer.start()
        localPort = sshServer.local_bind_port
        sshStatus = 1
        print(strConn + "SSH Tunnel Up: " + loopback + ":" + str(localPort))
    except:
        print(strConn + "Error SSH Tunnel")
        sshStatus = -1
        sshServer = -1
        localPort = -1

    return(sshStatus,sshServer,localPort)           

def sshStop(self,sshServer,strConn,num):
        sshServer.stop()
            print(strConn + "SSH" + str(num) + " stopped ...")

def run_mi_thread(i, script, loopback):
    connTelnet(i, script, loopback).run()

    #### Main ####
if __name__ == '__main__':

    progNumThreads = 40
    n = 1010
    a = '99.0.0.0'
    ipaddress = ip.IPv4Address(a)
    routers = [(ipaddress+x).exploded for x in range(1,n)]

    threads_list    = Pool(progNumThreads)
    for i, router in enumerate(routers):

        # We generate the config file
        script     = "blablabla\n"
        threads_list.apply_async(run_mi_thread, args=(i, script, router))

    threads_list.close()
    threads_list.join()

因此,如前所述,如果len(threads_list) <= 1000,将服务所有路由器。如果len(threads_list) > 1000,则仅服务前 1000 个路由器。

更重要的是:这个数字是 1000 非常奇怪。而且它总是一样的。不会随着程序的多次运行而改变。

它会与一些并行套接字的数量有关吗?SSH 隧道的数量?

谢谢!

标签: python-3.xthreadpoolpython-multithreading

解决方案


推荐阅读