Python - 并行运行多个get请求并在第一次响应时停止

时间:2018-02-08 05:09:31

标签: python parallel-processing python-requests python-multiprocessing

Python 3.4

请求2.18

我想进行多次requests.get次调用,然后返回获得响应的第一个调用,停止其余调用。最好的方法是什么?

编辑:我最终使用了python的multiprocessing模块和一个队列来实现结果,就像评论中提出的petre一样。这是代码:

from multiprocessing import Queue, Process
from multiprocessing.queues import Empty
from requests import head


def _req(url, queue):
    a = head(url)
    if a.status_code == 200:
        queue.put(a)
    return


def head_all_get_first(urls):
    jobs = []
    q = Queue()
    for url in urls:
        p = Process(target=_req, args=(url, q))
        jobs.append(p)
    for p in jobs:
        p.start()
    try:
        ret = q.get(timeout=20)  # blocking get - wait at most 20 seconds for a return
    except Empty:  # thrown if the timeout is exceeded
        ret = None
    for p in jobs:
        p.terminate()
    return ret

1 个答案:

答案 0 :(得分:2)

让我们看看可能性:

Python使用基于GIL的执行步进主要用于pure-[SERIAL]代码执行,因此最多可以达到"just"-[CONCURRENT]代码执行流程,而不是true-[PARALLEL]系统调度(进一步的细节超出了这篇文章,但现在不需要提出下面提到的选项。)

您的描述可以填充以下任何一种:
- 使用分布式系统(协调,多代理,双向通话处理器网络)
- 使用基于GIL多路复用的python基于线程的后端(如 multiprocessing ) - 使用基于GIL的python子流程后端(如 joblib

在所有情况下,这种代码执行基础架构的设置和终止的“成本”总和会有所不同(基于子进程的基础架构将是最昂贵的,因为它始终首先生成< strong> python解释器的初始状态的完整副本,包括所有的内存分配等,这对于“小块肉加工”非常昂贵,因此如果需要速度和剃须 - 关闭任何延迟到任何几分之一毫秒,可以直接排除这一个。)

(最好的半持久性)多代理网络的一个很好的例子是使用 ZeroMQ nanomsg 代理间中介工具(其中包含广泛的传输类{ inproc:// | ipc:// | tcp:// | ... | vmci:// }允许人们在本地/分布式布局中运行智能解决方案,并且达到“第一回答”状态可以智能,快速且廉价地“广告”给所有其他合作代理人,那不是第一个。

enter image description here

Ventilator Sink 角色都可以在相同的python进程,无论是类方法还是命令式代码的一些本地多路复用部分的形式,并且统一的 PUSH -strategy可以变得更加智能,如果是非同类的任务即将实施(但是,运行智能多代理处理网络的原则是可行的方法)。