Python线程似乎冻结了机器

2024-04-19 10:35:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用python线程解析网站IP地址。这是我解决问题的工作进程。这是一个守护进程线程。你知道吗

def get_ip_worker():
    """This is the worker (thread) process for parsing ips, this process takes domain from the q processes it
    and then saves it to another q"""

    socket.setdefaulttimeout(3)
    while True:
        domain = domains_q.get()
        try:
            addr_info = socket.getaddrinfo(domain, 80, 0, 0, socket.SOL_TCP)
            for family, socktype, proto, name, ip in addr_info:
                if family == 2: #okay it's ipv4
                    ip, port = ip
                    processed_q.put((ip, domain))
                elif family == 10: #okay it's ipv6
                    ip, port, no_1, no_2 = ip
                    processed_q.put((ip, domain))
        except:
            pass
            #print 'Socket Error'

        domains_q.task_done()

EDIT:domain=domains\u q.get()此行阻塞,直到队列中有可用的项目为止。你知道吗

当我在300个线程上运行这个程序时,问题就来了,平均负载似乎还可以,但是简单的ls-la需要5秒,而且一切都很慢。我哪里出错了?我应该使用异步还是多处理?你知道吗


Tags: theipinfoforget进程domainit
1条回答
网友
1楼 · 发布于 2024-04-19 10:35:39

你真的需要用300个线程并行处理300个连接吗?我从未尝试过创建那么多线程,但这可能是个问题。而这绝对不是解决问题的好办法。通常还有其他选择。首先,您不需要300个线程来侦听300个连接。创建一些似乎可以在硬件和操作系统上工作的线程。使用单个线程从主队列中检索请求,然后将它们传递给来自thread pool的线程。你知道吗

顺便说一句,检查“从队列中检索”操作是否真的阻塞并等待队列是否为空。如果没有,循环可以一直执行,而不取决于是否有传入请求。你知道吗

您可能真正需要的是套接字的非阻塞模式和select.select()之类的模式,以等待某个套接字准备好读或写。你可以自己写代码。如果您不想这样做,那么像gevent(或twisted)这样的好的异步网络库可能有助于改进程序的体系结构。利用多核CPU的全部功能是一个单独的问题,但我听说有一些解决方案,至少对于gevent(它们基于运行多个进程的gunicorn,从未尝试过)。但我认为您遇到的问题不是执行速度问题,而是需要一次有效地等待许多对象的I/O。如果是这样的话,请避免为此目的大量使用线程,这通常不仅在Python中是无效的,甚至在没有GIL的语言中也是无效的,这些语言更适合多线程编程。multiprocessing避免了GIL,但是增加了它自己的执行成本,所以我建议不要在这里使用它。你知道吗

相关问题 更多 >