8
votes

Python Interprète bloque les demandes DNS multithreadées?

Je viens de jouer autour d'un peu avec python et threads et réalisa même dans un script multithreadé, les demandes DNS bloquent. Considérez le script suivant:

du thread d'importation de filetage Prise d'importation p>

class Connection(Thread):
    def __init__(self, name, url):
        Thread.__init__(self)
        self._url = url
        self._name = name

    def run(self):
        print "Connecting...", self._name
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.setblocking(0)
            s.connect((self._url, 80))
        except socket.gaierror:
            pass #not interested in it
        print "finished", self._name


if __name__ == '__main__':
    conns = []
    # all invalid addresses to see how they fail / check times
    conns.append(Connection("conn1", "www.2eg11erdhrtj.com"))
    conns.append(Connection("conn2", "www.e2ger2dh2rtj.com"))
    conns.append(Connection("conn3", "www.eg2de3rh1rtj.com"))
    conns.append(Connection("conn4", "www.ege2rh4rd1tj.com"))
    conns.append(Connection("conn5", "www.ege52drhrtj1.com"))

    for conn in conns:
        conn.start()


7 commentaires

Avez-vous essayé simplement d'utiliser Socket.getaddrinfo (hôte, port) pour voir si cela a la même limitation? Malheureusement, je ne peux pas reproduire cela, car c'est un problème DNS. Dans la plupart des cas, vous devriez obtenir un "Gaierror: (-2," nom ou service non connu ")" plutôt rapidement.


Oui, j'ai essayé cela et j'ai la même limitation.


Je suis presque sûr que OSX utilise GettaDdrinfo à partir des bibliothèques BSD, ce qui a probablement la restriction énumérée par ci-dessous.


"N'est-il pas possible d'obtenir cette petite chose simple avec python?" Eh bien, tordu est python. C'est une bibliothèque python python. Vérifiez simplement son code source pour voir comment cela fait.


Je me demande si tordu souffrira sous les mêmes limitations lorsqu'il est exécuté sur Mac OS X


Ce ne sera pas. Twisted.Names est fait dans tous les Python et n'appelle pas du tout la fonction Hosts Gettaddrinfo. Des Documents API "Les fonctions exposées dans ce module peuvent être utilisées pour la résolution de noms asynchrone et les requêtes DNS".


Merde! C'est vrai. J'ai obtenu le même résultat. Je ne sais pas pourquoi Python suce dans cette région!


3 Réponses :


15
votes

Sur certains systèmes, GettaDdrinfo n'est pas un fil-coffre-fort. Python estime que certains systèmes de ce type sont FreeBSD, OpenBSD, NetBSD, OSX et VMS. Sur ces systèmes, Python maintient une serrure spécifiquement pour la Netdb (I.e. Gettaddrinfo et Amis).

Donc, si vous ne pouvez pas changer de système d'exploitation, vous devez utiliser une bibliothèque de résolveur différente (fil à fil), telle que Twisted.


3 commentaires

J'ai besoin de cela assez rapidement, mais je viens de commander un livre sur Twisted, les gens semblent vraiment comme ça, je ne peux pas être si mal après tout. Je vais essayer d'y entrer un peu, mais je suis vraiment occupé ces derniers temps.


Il existe d'autres bibliothèques de résolveur Python, telles que DNSPYPHON et PYDNS, qui pourraient être plus simples à utiliser que tordus. Ils ne sont probablement pas complètement vitrés (créant une nouvelle prise UDP pour chaque demande DNS, et donc potentiellement épuisants les numéros de port), mais cela peut ne pas être un problème si vous n'effectuez pas de nombreuses requêtes.


Je crois que curl / libcurl utilise le résolveur C-Ares pour cette même raison.



2
votes

Si c'est approprié, vous pouvez utiliser le module multiprocessionnaire > pour activer le parallélisme basé sur le processus xxx


1 commentaires

Est-ce une réponse ou une question? : P



2
votes

Envoyer des demandes DNS asynchroniquement à l'aide de noms tordus : xxx


0 commentaires