Je viens de jouer un peu avec python et les threads, et réalisé même dans un script multithread, les requêtes DNS bloquent. Considérez le script suivant:L'interpréteur Python bloque les requêtes DNS multithread?
de filetage import fil Prise d'importation
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()
Je ne sais pas exactement combien de temps le délai d'attente est, mais l'exécution de ce qui suit se produit:
- toutes les discussions commencent et je reçois mes impressions
- Toutes les xx secondes, un fil affiche fini, au lieu de tout à la fois
- T Les threads finissent séquentiellement, pas tous en même temps (timeout = le même pour tous!)
Donc, mon seul doute est que cela a à voir avec le GIL? Évidemment, les threads n'effectuent pas leur tâche simultanément, une seule connexion est tentée à la fois.
Est-ce que quelqu'un sait un moyen de contourner cela?
(asyncore ne aide pas, et je préfère ne pas utiliser tordu pour l'instant) est-il pas possible d'obtenir cette petite chose simple fait avec python?
Salutations, Tom
modifier:
Je suis sur MacOSX, je viens de laisser mon ami exécuter sur linux, et il ne fait obtenir les résultats que je voulais obtenir. Son retour de socket.connects() immédiatement, même dans un environnement non Threaded. Et même quand il met les douilles à bloquer, et le délai d'attente à 10 secondes, tous ses fils finissent en même temps.
Quelqu'un peut-il expliquer cela?
Avez-vous essayé simplement en utilisant socket.getaddrinfo (hôte, port) pour voir si cela a la même limitation? Je ne peux malheureusement pas reproduire cela, car c'est un problème de DNS. Dans la plupart des cas, vous devriez obtenir un "gaierror: (-2, 'Name ou service not known')" plutôt rapidement. – JimB
oui j'ai essayé ceci, et il a la même limitation. – Tom
Je suis à peu près sûr qu'OSX utilise getaddrinfo des bibliothèques BSD, qui a probablement la restriction listée ci-dessous par. –
JimB