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

Tom*_*Tom 8 python multithreading network-programming

我只是用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()
Run Code Online (Sandbox Code Playgroud)

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

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

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

有没有人知道这方面的方法?

(asyncore没有帮助,我现在不想使用twisted)是不是可以用python完成这个简单的小事?

问候,汤姆

编辑:

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

有谁能解释一下?

Mar*_*wis 15

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

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