Python - 运行 多个并行获取请求并在第一次响应时停止
Python - Run multiple get requests in parallel and stop on first response
Python 3.4
请求 2.18
我想进行多次 requests.get
调用,return 第一个得到响应,停止其余调用。最好的方法是什么?
编辑:我最终使用 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
让我们看看可能性:
Python 将基于 GIL 的执行步进主要用于 pure-[SERIAL]
code-execution, thus a maximum one can reach is a "just"-[CONCURRENT]
flow of code-execution, not a true-[PARALLEL]
系统调度(进一步的细节远不止于此 post,但现在不需要介绍下面提到的选项) .
您的描述可以这样填充:
- 使用分布式系统(一个协调的、多代理的、双向对话的处理器网络)
- 使用 GIL 多路复用 python 基于线程的后端(如 multiprocessing
)
- 使用独立于 GIL python 子进程的后端(如 joblib
)
在所有情况下,这种代码执行基础结构的设置和终止的 "costs" 总和会有所不同(其中基于子流程的将是最昂贵的,因为它总是首先生成 python 解释器 初始状态的 完整副本,包括它的所有内存分配等,这对 "small pieces of meat to process" 来说非常昂贵,所以如果在需要速度和将任何延迟减少到毫秒的任何分数的情况下,可以直接排除这个。
(最好是半持久的)多代理网络的一个很好的例子是使用 ZeroMQ 或 nanomsg 代理间调解工具(其中广泛的传输 classes { inproc:// | ipc:// | tcp:// | ... | vmci:// }
允许人们在 local/distributed 布局中运行智能解决方案,并且达到 "first answered" 状态可能是智能、快速和便宜的"advertised" 所有其他合作代理人,他们不是第一个。
Ventilator
和Sink
角色可以在同一个 python 进程中,可以是 class 方法,也可以是命令式代码的一些局部复用部分的形式,也可以是统一的PUSH
-如果非同质任务即将得到实施,策略可能会变得更智能(然而,运行多智能体处理智能网络的原则是可行的方法).
Python 3.4
请求 2.18
我想进行多次 requests.get
调用,return 第一个得到响应,停止其余调用。最好的方法是什么?
编辑:我最终使用 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
让我们看看可能性:
Python 将基于 GIL 的执行步进主要用于 pure-[SERIAL]
code-execution, thus a maximum one can reach is a "just"-[CONCURRENT]
flow of code-execution, not a true-[PARALLEL]
系统调度(进一步的细节远不止于此 post,但现在不需要介绍下面提到的选项) .
您的描述可以这样填充:
- 使用分布式系统(一个协调的、多代理的、双向对话的处理器网络)
- 使用 GIL 多路复用 python 基于线程的后端(如 multiprocessing
)
- 使用独立于 GIL python 子进程的后端(如 joblib
)
在所有情况下,这种代码执行基础结构的设置和终止的 "costs" 总和会有所不同(其中基于子流程的将是最昂贵的,因为它总是首先生成 python 解释器 初始状态的 完整副本,包括它的所有内存分配等,这对 "small pieces of meat to process" 来说非常昂贵,所以如果在需要速度和将任何延迟减少到毫秒的任何分数的情况下,可以直接排除这个。
(最好是半持久的)多代理网络的一个很好的例子是使用 ZeroMQ 或 nanomsg 代理间调解工具(其中广泛的传输 classes { inproc:// | ipc:// | tcp:// | ... | vmci:// }
允许人们在 local/distributed 布局中运行智能解决方案,并且达到 "first answered" 状态可能是智能、快速和便宜的"advertised" 所有其他合作代理人,他们不是第一个。
Ventilator
和Sink
角色可以在同一个 python 进程中,可以是 class 方法,也可以是命令式代码的一些局部复用部分的形式,也可以是统一的PUSH
-如果非同质任务即将得到实施,策略可能会变得更智能(然而,运行多智能体处理智能网络的原则是可行的方法).