我使用asyncio.Semaphore
在有序的List
上运行了许多并行执行。
async def send_cus(cus_id):
async with ClientSession(connector=TCPConnector(limit=0)) as session:
num_parallel = asyncio.Semaphore(20)
async def send_cust_2(cust_id):
async with num_parallel:
# do something ...
tasks = list(
send_cust_2(cust_id)
for cus_id in my_ordered_lst
)
await asyncio.gather(*tasks)
关键是它以无序的方式执行,而与my_ordered_lst
的顺序无关。我理解这是因为如果不同步元素,我们就无法保证线程或进程分叉的执行顺序。
有没有一种方法可以在整个List
中获得有序执行,同时仍然具有并行执行?喜欢第一次发送。获取锁,发送然后发送,获取锁,等等
在Python 3.7之前,asyncio.gather()
以任意顺序启动任务。对于3.7,为了提高效率,它被重写了,副作用是它现在按照指定的顺序创建任务。
在Python 3.6及更早版本中,您可以通过按所需顺序手动生成任务,然后调用gather
等待任务完成来解决此问题:
tasks = [asyncio.create_task(send_cust_2(cust_id))
for cust_id in my_ordered_lst]
await asyncio.gather(*tasks)
请注意,这只会按指定顺序启动任务。它们如何在第一个await
之后继续执行将取决于各个任务做什么以及它们各自操作的时序。