发出异步 HTTP 请求并继续执行循环
Make an async HTTP request and continue executing the loop
我有一个简单的 python 函数,伪代码如下:
while True:
# 1 - CPU Intensive calculations(Synchronous)
# 2 - Take the result from the synchronous calculation and POST it to a server
while 循环 运行 永远存在,并在循环的前半部分进行 CPU 密集计算。所有这些都是 运行 同步进行的,没关系。
我想做的是通过使 POST 请求异步来节省一些时间。 while 循环需要永远 运行,但是我希望异步发出请求,以便循环可以继续下一次迭代,而无需等待请求解决。
想知道在不使用任何额外的情况下使用 asyncio 实现此目的的最佳方法是什么 threads/greenlets/processes
编辑
在这里发布问题之前,我尝试过这种方法:
async def example_function():
# Synchronous CPU Intensive calculations
client = httpx.AsyncClient()
# Make a call to the REST API
await client.post()
async def main():
while True:
await asyncio.gather(example_function(), example_function())
if __name__ == "__main__":
asyncio.run(main())
我完全不熟悉 python 的异步编程。我尝试了 gather 方法,但是我的实现方法的缺陷是 example_function() 的第二次迭代不会异步生成 POST 请求。我知道 asyncio.gather() 基本上为传递给它的每个函数安排了一个任务,我有一个任务在等待,它继续执行下一个任务。但是,我需要 运行 example_function() 永远循环,而不仅仅是 n 次
Would like to know what is the best way to achieve this with asyncio without using any extra threads/greenlets/processes
如果你的代码是同步的,你将需要使用一些形式的多线程,但你可以通过asyncio为那个目的。例如,如果您 运行 通过 loop.run_in_executor()
同步代码,事件循环将在计算 运行ning 期间保持旋转,并且将处理置于后台的任务。这允许您在后台使用 asyncio.create_task()
到 运行 循环的第二部分,或者更准确地说,与事件循环的其余部分并行使用。
def calculations(arg1):
# ... synchronous code here
async def post_result(result, session):
async with session.post('http://httpbin.org/post',
data={'key1': result}) as resp:
resp.raise_for_status()
async def main():
loop = asyncio.get_event_loop()
with aiohttp.ClientSession() as session:
while True:
# run the sync code off-thread so the event loop
# continues running, but wait for it to finish
result = await loop.run_in_executor(None, calculations, arg1)
# don't await the task, let it run in the background
asyncio.create_task(post_result(result, session))
if __name__ == '__main__':
asyncio.run(main())
我有一个简单的 python 函数,伪代码如下:
while True:
# 1 - CPU Intensive calculations(Synchronous)
# 2 - Take the result from the synchronous calculation and POST it to a server
while 循环 运行 永远存在,并在循环的前半部分进行 CPU 密集计算。所有这些都是 运行 同步进行的,没关系。 我想做的是通过使 POST 请求异步来节省一些时间。 while 循环需要永远 运行,但是我希望异步发出请求,以便循环可以继续下一次迭代,而无需等待请求解决。
想知道在不使用任何额外的情况下使用 asyncio 实现此目的的最佳方法是什么 threads/greenlets/processes
编辑
在这里发布问题之前,我尝试过这种方法:
async def example_function():
# Synchronous CPU Intensive calculations
client = httpx.AsyncClient()
# Make a call to the REST API
await client.post()
async def main():
while True:
await asyncio.gather(example_function(), example_function())
if __name__ == "__main__":
asyncio.run(main())
我完全不熟悉 python 的异步编程。我尝试了 gather 方法,但是我的实现方法的缺陷是 example_function() 的第二次迭代不会异步生成 POST 请求。我知道 asyncio.gather() 基本上为传递给它的每个函数安排了一个任务,我有一个任务在等待,它继续执行下一个任务。但是,我需要 运行 example_function() 永远循环,而不仅仅是 n 次
Would like to know what is the best way to achieve this with asyncio without using any extra threads/greenlets/processes
如果你的代码是同步的,你将需要使用一些形式的多线程,但你可以通过asyncio为那个目的。例如,如果您 运行 通过 loop.run_in_executor()
同步代码,事件循环将在计算 运行ning 期间保持旋转,并且将处理置于后台的任务。这允许您在后台使用 asyncio.create_task()
到 运行 循环的第二部分,或者更准确地说,与事件循环的其余部分并行使用。
def calculations(arg1):
# ... synchronous code here
async def post_result(result, session):
async with session.post('http://httpbin.org/post',
data={'key1': result}) as resp:
resp.raise_for_status()
async def main():
loop = asyncio.get_event_loop()
with aiohttp.ClientSession() as session:
while True:
# run the sync code off-thread so the event loop
# continues running, but wait for it to finish
result = await loop.run_in_executor(None, calculations, arg1)
# don't await the task, let it run in the background
asyncio.create_task(post_result(result, session))
if __name__ == '__main__':
asyncio.run(main())