Проблемы с таймаутом и высокой загрузкой процессора при использовании нескольких потоков подключения telnet в python - PullRequest
0 голосов
/ 21 декабря 2011

Я хочу подключиться к нескольким хостам telnet, используя потоки в python, но я наткнулся на проблему, которую не могу решить.

Использование следующего кода в MAC OS X Lion / Python 2.7

import threading,telnetlib,socket

class ReaderThread(threading.Thread):
    def __init__(self, ip, port): 
        threading.Thread.__init__(self)
        self.ip = ip
        self.port = port
        self.telnet_con = telnetlib.Telnet()

    def run(self):
        try:
            print 'Start %s' % self.ip
            self.telnet_con.open(self.ip,self.port,30)
            print 'Done %s' % self.ip
        except socket.timeout:
            print 'Timeout in %s' % self.ip

    def join(self):
        self.telnet_con.close()

ta = []

t1 = ReaderThread('10.0.1.162',9999)
ta.append(t1)
t2 = ReaderThread('10.0.1.163',9999)
ta.append(t2)

for t in ta:
    t.start()
print 'Threads started\n'

В целом это работает, но для подключения одного из потоков (не всегда одного и того же) требуется много времени (около 20 секунд, а иногда даже время ожидания).В течение этого ужасно долгого времени соединения (во всей локальной сети) загрузка процессора также возрастает до 100%.

Еще более странным является тот факт, что если я использую только один поток в массиве, он всегда работаетбезотказно.Так что это должно быть как-то связано с использованием нескольких потоков.

Я уже добавил записи имени хоста для всех IP-адресов, чтобы избежать проблемы с поиском DNS.Это не имеет значения.

Заранее благодарен за вашу помощь.

С уважением

senexi

1 Ответ

0 голосов
/ 22 декабря 2011

Хорошо, вы переопределили join (), и вы не должны этого делать.Основной поток вызывает join () для каждого потока, когда основной поток завершает работу, что находится сразу после последней строки в вашем коде.Поскольку ваш метод join () возвращается до фактического завершения потока telnet, Python сбивается с толку и пытается снова вызвать join (), что и вызывает использование процессора на 100%.Попробуйте вставить оператор print в метод join ().

Ваша реализация join () пытается закрыть сокет (возможно, пока другой поток все еще пытается открыть соединение), и это можетбыть тем, что заставляет ваши потоки telnet никогда не заканчиваться.

...