小编典典

Python解释器会阻止多线程DNS请求?

python

我只是玩弄了一些python和线程,并意识到即使在多线程脚本中,DNS请求也被阻止了。考虑以下脚本:

从线程导入线程导入套接字

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()

我不知道确切的超时时间,但是在运行此操作时会发生以下情况:

  1. 所有线程开始,我得到我的打印输出
  2. 每xx秒,一个线程显示完成,而不是一次全部显示
  3. 线程按顺序完成,而不是一次完成(超时=全部相同!)

所以我唯一的猜测是这与GIL有关吗?显然,线程不会并发执行任务,一次只能尝试一个连接。

有谁知道解决这个问题的方法吗?

asyncore并 没有帮助,我现在不希望使用 twisted )能否用python完成这个简单的小事情?

汤姆,问候

编辑:

我在MacOSX上,我只是让我的朋友在linux上运行它,而他确实得到了我希望得到的结果。即使在非线程环境中,他的socket.connects()也会立即返回。即使将套接字设置为阻塞,并且将超时设置为10秒,他的所有线程也会同时完成。

谁能解释一下?


阅读 212

收藏
2020-12-20

共1个答案

小编典典

在某些系统上,getaddrinfo不是线程安全的。Python认为其中一些系统是FreeBSD,OpenBSD,NetBSD,OSX和VMS。在那些系统上,Python专门为netdb(即getaddrinfo和友人)维护一个锁。

因此,如果无法切换操作系统,则必须使用其他(线程安全的)解析程序库,例如twisted的。

2020-12-20