有一个函数可以阻止事件循环(例如,该函数发出API请求)。我需要发出连续的请求流,这些请求将并行运行,但不同步。因此,每个下一个请求将在前一个请求完成之前开始。
因此,我在loop.run_in_executer()
解决方案中找到了this solved question,并在开始时使用它:
import asyncio
import requests
#blocking_request_func() defined somewhere
async def main():
loop = asyncio.get_event_loop()
future1 = loop.run_in_executor(None, blocking_request_func, 'param')
future2 = loop.run_in_executor(None, blocking_request_func, 'param')
response1 = await future1
response2 = await future2
print(response1)
print(response2)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
这工作得很好,请求并行运行,但是我的任务有一个问题--在这个例子中,我们在开始时创建一组任务/future,然后同步运行这个组。2但是我需要这样的东西:
1. Sending request_1 and not awaiting when it's done.
(AFTER step 1 but NOT in the same time when step 1 starts):
2. Sending request_2 and not awaiting when it's done.
(AFTER step 2 but NOT in the same time when step 2 starts):
3. Sending request_3 and not awaiting when it's done.
(Request 1(or any other) gives the response)
(AFTER step 3 but NOT in the same time when step 3 starts):
4. Sending request_4 and not awaiting when it's done.
(Request 2(or any other) gives the response)
and so on...
我尝试使用asyncio.TaskGroup()
:
async def request_func():
global result #the list of results of requests defined somewhere in global area
loop = asyncio.get_event_loop()
result.append(await loop.run_in_executor(None, blocking_request_func, 'param')
await asyncio.sleep(0) #adding or removing this line gives the same result
async def main():
async with asyncio.TaskGroup() as tg:
for i in range(0, 10):
tg.create_task(request_func())
所有这些都得出了相同的结果:首先我们定义了一组任务/future,然后才同步和并发地运行这组任务。2但是有没有一种方法可以并发地运行所有这些请求,但是“在流中”呢?
如果我的解释不够清楚,我试着形象化。
What I have for now
What I need
2条答案
按热度按时间y0u0uwnf1#
我想这可能是你想要的。你不必等待每个请求--
run_in_executor
函数返回一个Future
。你可以附加一个回调函数来代替等待。所有的请求都在开始时启动,但是它们并不都并行执行,因为线程的数量受到ThreadPool的限制。如果需要,您可以调整线程的数量。
这里我用time. sleep模拟了一个阻塞调用。我需要一种方法来防止main()在所有回调发生之前结束,所以我使用
gather
来实现这个目的。您也可以等待一段时间,但是gather
更干净。如果我不明白您想要什么,请向我道歉,但是我认为您希望避免在每次调用时都使用
await
,我尝试展示了一种方法。4dc9hkyq2#
直接引用Python文档,asyncio库文档的代码片段解释了如何使用asyncio并发运行阻塞代码,使用
to_thread
方法创建任务您可以在此处找到更多信息-https://docs.python.org/3/library/asyncio-task.html#running-in-threads