Problème avec multi threaded Python application et les connexions socket

Je suis étudier un problème avec un Python application qui s'exécute sur une machine Ubuntu avec 4G de RAM. L'outil sera utilisé pour la vérification des serveurs (nous préférons rouler nos propres outils). Il utilise des threads pour se connecter à de nombreux serveurs et de nombreuses connexions TCP échouer. Cependant, si j'ajoute un délai de 1 seconde entre le coup d'envoi de chaque fil, puis la plupart des connexions à réussir. J'ai utilisé ce script simple pour enquêter sur ce qui pourrait se passer:

#!/usr/bin/python

import sys
import socket
import threading
import time

class Scanner(threading.Thread):
    def __init__(self, host, port):
        threading.Thread.__init__(self)
        self.host = host
        self.port = port
        self.status = ""

    def run(self):
        self.sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sk.settimeout(20)
        try:
            self.sk.connect((self.host, self.port))
        except Exception, err:
            self.status = str(err)
        else:
            self.status = "connected"
        finally:
            self.sk.close()


def get_hostnames_list(filename):
    return open(filename).read().splitlines()

if (__name__ == "__main__"):
    hostnames_file = sys.argv[1]
    hosts_list = get_hostnames_list(hostnames_file)
    threads = []
    for host in hosts_list:
        #time.sleep(1)
        thread = Scanner(host, 443)
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()
        print "Host: ", thread.host, " : ", thread.status

Si je l'exécute avec le temps.sleep(1) a commenté contre, disons, 300 abrite de nombreuses connexions échouent avec une erreur de dépassement de délai, alors qu'ils n'ont pas de timeout si je mets le délai d'une seconde. Je l'ai fait essayer l'application sur une autre distro Linux en cours d'exécution sur une machine plus puissante et il n'y avait pas autant de connecter des erreurs? Est-ce dû à un noyau de limitation? Est-ce que je peux faire pour obtenir la connexion de travailler sans mettre en retard?

Mise à JOUR

J'ai aussi essayé un programme qui a limité le nombre de threads disponibles dans une piscine. En réduisant ce jusqu'à 20 je peux obtenir tous se connecte à travailler, mais il vérifie seulement environ 1 seconde. Donc, tout ce que j'ai essayer (à mettre dans un sleep(1) ou de limiter le nombre de threads simultanés) je ne semble pas en mesure de vérifier plus de 1 hôte à chaque seconde.

Mise à JOUR

Je viens de trouver cette question qui semble similaire à ce que je vois.

Mise à JOUR

Je me demande si l'écriture de cette aide tordu pourrait aider? Quelqu'un pourrait-il montrer ce que mon exemple ressemblerait écrite à l'aide de tordu?

Voyez-vous beaucoup de connexions dans l'état TIME_WAIT (netstat)? stackoverflow.com/questions/410616/...
L'accès au réseau n'est pas simultanée en Python lors de l'utilisation des threads, vous devez utiliser le multitraitement ou quelque chose comme gevent ou eventlet. Voir la réponse de J. F. Sebastian
Python comme une règle de communiqués de GIL tout faire des I/O de sorte que vous pouvez utiliser les threads, mais vous ne devriez pas créer des milliers d'entre eux juste pour vous connecter à des milliers d'hôtes.

OriginalL'auteur VacuumTube | 2011-01-24