Python 如何多次并发运行同一异步函数?

Python 如何多次并发运行同一异步函数?,python,concurrency,python-asyncio,Python,Concurrency,Python Asyncio,设置: clients = {} async def function_a(ws_message): # this is being called each time when a new message arrives if ws_message == 'signal_message': for client in clients: await function_b(client) async def function_b(client):

设置:

clients = {}

async def function_a(ws_message): # this is being called each time when a new message arrives
    if ws_message == 'signal_message':
        for client in clients:
             await function_b(client)

async def function_b(client):
    # get client parameters
    # make an API request with those parameters
因此,我有一个由客户机对象组成的客户机数组。还有两个异步函数,一个用于处理来自WebSocket的传入消息,另一个用于对给定的客户端对象执行一些API调用

当某个消息从WebSocket连接到达时,函数_a应该检测到它并在客户端数组中启动for循环。对于clients数组中的每个client对象,我希望触发函数_b。但是函数_b应该为每个客户机并发运行

示例代码:

clients = {}

async def function_a(ws_message): # this is being called each time when a new message arrives
    if ws_message == 'signal_message':
        for client in clients:
             await function_b(client)

async def function_b(client):
    # get client parameters
    # make an API request with those parameters
使用asyncio.gather()更新| |代码

因此,我用asyncio.gather()更新了我的实际代码,但每个函数任务之间仍有约500毫秒的延迟。我不确定,但我想这是因为我的函数_b有一些非异步阻塞代码,这要感谢请求库

正如我所说,这也不起作用

问题:

clients = {}

async def function_a(ws_message): # this is being called each time when a new message arrives
    if ws_message == 'signal_message':
        for client in clients:
             await function_b(client)

async def function_b(client):
    # get client parameters
    # make an API request with those parameters
现在函数_b被触发没有任何问题,但是函数_b运行大约500毫秒,函数_a的等待调用等待函数完成。例如,在接收到WebSocket消息后,客户端数组中第二个客户端对象的函数_b过程需要约1000毫秒才能完成。显然,每次通话的延迟都会越来越大

解决方案?


Have可以修复此问题,使每个函数_b进程可以并发运行吗?提前感谢。

要从协同例程中并行启动代码,您必须使用它创建一个“任务”(并暂停,而不必等待任务)

调用完成包装、调用、执行和包装 一次性返回所有值:

clients = {}

async def function_a(ws_message): # this is being called each time when a new message arrives
    if ws_message == 'signal_message':
        await asyncio.gather(*(function_b(client) for client in clients))
交互式提示的完整示例:


In [8]: import asyncio

In [9]: async def coro1():
   ...:     await asyncio.sleep(1)
   ...:     print("step 1")
   ...:     await asyncio.sleep(1)
   ...:     print("step 2")
   ...: 
   ...: 
   ...: 

In [10]: async def coro2():
    ...:     await asyncio.gather(*(coro1() for i in range(5)))
    ...: 

In [11]: asyncio.run(coro2())
step 1
step 1
step 1
step 1
step 1
step 2
step 2
step 2
step 2
step 2
可以看出,所有co例程并行运行,输出第一次打印的结果,1s后,显示第二次打印调用的输出


如果没有观察到并行性,这可能是由于您没有让主循环自己等待其他协例程执行的协例程造成的。对于CPU受限的代码,只能通过在不同的线程或进程中运行函数来实现并行性。

我已经尝试了您的解决方案,但根本没有帮助。它仍然一个接一个地执行函数。更新了我的问题。函数b的代码中是否有
wait
暂停?如果它是同步的,asyncio就不能并行运行。@jsbueno不,它没有任何
asyncio.sleep()
time.sleep()
。它唯一的同步功能是由请求模块处理的API调用。现在我正在转换为aiohttp,而不是请求,看看它是否有任何区别。