当前位置: 首页 > 面试题库 >

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

龚彬
2023-03-14
问题内容

我只是玩弄了一些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秒,他的所有线程也会同时完成。

谁能解释一下?


问题答案:

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

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



 类似资料:
  • 问题内容: 我知道这似乎是一个荒谬的问题,但是我必须在与部门中其他人共享的计算服务器上定期运行作业,当我开始10个作业时,我真的希望它只占用10个核心而不是更多; 我不在乎每次运行一个内核所需的时间是否更长:我只是不想让它侵占其他人的领土,这将需要我放弃工作等等。我只想拥有10个坚实的核心,仅此而已。 更具体地说,我在基于Python 2.7.3和numpy 1.6.1的Redhat上使用Enth

  • 问题内容: 如何使多线程python程序响应Ctrl + C键事件? 编辑: 代码是这样的: 我试图在所有线程上删除join(),但仍然无法正常工作。是否因为每个线程的run()过程中的锁段? 编辑: 上面的代码应该可以工作,但是当当前变量在5,000-6,000范围内并遍历以下错误时,它总是会中断 问题答案: 在启动主线程之前,将除主线程之外的每个线程都设为守护进程(在2.6或更高版本中,在2.

  • 我正在尝试用Python编写一个程序。我想写的是一个脚本,它会立即向用户返回一条友好的消息,但会在后台生成一个长的子进程,它会处理几个不同的文件,并将它们写入一个祖父文件。我已经做了一些关于线程和处理的教程,但我遇到的是,无论我尝试什么,程序都会一直等待,直到子进程完成,然后才会向用户显示前面提到的友好消息。以下是我尝试过的: 线程示例: 我读过这些关于多线程的SO帖子如何在Python中使用线程

  • 本文向大家介绍理解python多线程(python多线程简明教程),包括了理解python多线程(python多线程简明教程)的使用技巧和注意事项,需要的朋友参考一下 对于python 多线程的理解,我花了很长时间,搜索的大部份文章都不够通俗易懂。所以,这里力图用简单的例子,让你对多线程有个初步的认识。 单线程   在好些年前的MS-DOS时代,操作系统处理问题都是单任务的,我想做听音乐和看电影两

  • 本文向大家介绍详解Python多线程,包括了详解Python多线程的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家解析了Python多线程,供大家参考,具体内容如下 1、多线程的理解 多进程和多线程都可以执行多个任务,线程是进程的一部分。线程的特点是线程之间可以共享内存和变量,资源消耗少(不过在Unix环境中,多进程和多线程资源调度消耗差距不明显,Unix调度较快),缺点是线程之间的同步和

  • 问题内容: 我正在编写一个程序,它将监视特定目录中包含下载URL的新文件。一旦检测到新文件,它将在父级继续监视目录的同时创建一个新过程来进行实际下载。我正在使用来自的界面。我的问题是,除非我调用process.join(),否则子进程仍在运行,但是process.join()是一个阻止函数,无法实现创建子进程来处理实际下载的目的。 我的问题是,是否有一种以非阻塞方式加入子进程的方法,该方法将允许父