我只是玩弄了一些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()
我不知道确切的超时时间,但是在运行此操作时会发生以下情况:
所以我唯一的猜测是这与GIL有关吗?显然,线程不会并发执行任务,一次只能尝试一个连接。
有谁知道解决这个问题的方法吗?
( asyncore并 没有帮助,我现在不希望使用 twisted )能否用python完成这个简单的小事情?
汤姆,问候
我在MacOSX上,我只是让我的朋友在linux上运行它,而他确实得到了我希望得到的结果。即使在非线程环境中,他的socket.connects()也会立即返回。即使将套接字设置为阻塞,并且将超时设置为10秒,他的所有线程也会同时完成。
谁能解释一下?
在某些系统上,getaddrinfo不是线程安全的。Python认为其中一些系统是FreeBSD,OpenBSD,NetBSD,OSX和VMS。在那些系统上,Python专门为netdb(即getaddrinfo和友人)维护一个锁。
因此,如果无法切换操作系统,则必须使用其他(线程安全的)解析程序库,例如twisted的。