Python - 如何使用 asyncio 异步执行任务 运行
Python - How to make tasks run asynchronously using asyncio
我试图为列表中的单个客户端同时 运行 2 个任务,但它没有按预期工作 - 任务仍然 运行 同步(请参阅 Output
).你能帮我理解我的代码有什么问题吗?谢谢。
代码
#!/usr/bin/env python3
import asyncio
async def do_b(client):
print('{}: doing b...'.format(client))
await asyncio.sleep(1)
print('{}: b is done!'.format(client))
async def do_a(client):
print('{}: doing a...'.format(client))
await asyncio.sleep(1)
print('{}: a is done!'.format(client))
async def loop_a():
clients = ['CLIENT-1', 'CLIENT-2', 'CLIENT-3', 'CLIENT-4', 'CLIENT-5']
for client in clients:
task1 = asyncio.ensure_future(do_a(client))
task2 = asyncio.ensure_future(do_b(client))
await asyncio.gather(task1, task2)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(loop_a())
loop.close()
输出
CLIENT-1: doing a...
CLIENT-1: doing b...
CLIENT-1: a is done!
CLIENT-1: b is done!
CLIENT-2: doing a...
CLIENT-2: doing b...
CLIENT-2: a is done!
CLIENT-2: b is done!
CLIENT-3: doing a...
CLIENT-3: doing b...
CLIENT-3: a is done!
CLIENT-3: b is done!
CLIENT-4: doing a...
CLIENT-4: doing b...
CLIENT-4: a is done!
CLIENT-4: b is done!
CLIENT-5: doing a...
CLIENT-5: doing b...
CLIENT-5: a is done!
CLIENT-5: b is done!
编辑:
另一个问题。我如何让它不按照列表中的顺序执行?因为目前,CLIENT-1
正被 CLIENT-2
阻止,与其他客户端一样,我试图避免这种情况。这可能吗?
CLIENT-1: doing a...
CLIENT-2: doing a...
CLIENT-1: doing b...
CLIENT-3: doing a...
CLIENT-1: a is done!
CLIENT-1: b is done!
CLIENT-2: a is done!
CLIENT-3: a is done!
CLIENT-2: doing b...
CLIENT-2: b is done!
CLIENT-3: doing b...
CLIENT-3: b is done!
首先,这两个任务 不是 运行 同步的,从 doing b...
不断出现在 doing a...
和 a is done!
.
每对任务都在下一个客户开始之前完成,但那是因为您明确要求发生这种情况。如果您不想 await
每对,只需……不要 await
每对。例如:
futs = []
for client in clients:
futs.append(asyncio.ensure_future(do_a(client)))
futs.append(asyncio.ensure_future(do_b(client)))
await asyncio.gather(*futs)
a
和 b
同时 运行ning 并且输出显示了这一点。客户端 1、2、3、4 和 5 按顺序 运行ning 因为它们之间有一个 await asyncio.gather
。
您可以将所有任务合并到一个列表中,使它们同时 运行:
async def loop_a():
clients = ['CLIENT-1', 'CLIENT-2', 'CLIENT-3', 'CLIENT-4', 'CLIENT-5']
tasks = []
for client in clients:
tasks.append(asyncio.ensure_future(do_a(client)))
tasks.append(asyncio.ensure_future(do_b(client)))
await asyncio.gather(*tasks)
现在打印:
CLIENT-1: doing a...
CLIENT-1: doing b...
CLIENT-2: doing a...
CLIENT-2: doing b...
CLIENT-3: doing a...
CLIENT-3: doing b...
CLIENT-4: doing a...
CLIENT-4: doing b...
CLIENT-5: doing a...
CLIENT-5: doing b...
CLIENT-1: a is done!
CLIENT-2: a is done!
CLIENT-3: b is done!
CLIENT-1: b is done!
CLIENT-3: a is done!
CLIENT-2: b is done!
CLIENT-4: a is done!
CLIENT-5: b is done!
CLIENT-4: b is done!
CLIENT-5: a is done!
我试图为列表中的单个客户端同时 运行 2 个任务,但它没有按预期工作 - 任务仍然 运行 同步(请参阅 Output
).你能帮我理解我的代码有什么问题吗?谢谢。
代码
#!/usr/bin/env python3
import asyncio
async def do_b(client):
print('{}: doing b...'.format(client))
await asyncio.sleep(1)
print('{}: b is done!'.format(client))
async def do_a(client):
print('{}: doing a...'.format(client))
await asyncio.sleep(1)
print('{}: a is done!'.format(client))
async def loop_a():
clients = ['CLIENT-1', 'CLIENT-2', 'CLIENT-3', 'CLIENT-4', 'CLIENT-5']
for client in clients:
task1 = asyncio.ensure_future(do_a(client))
task2 = asyncio.ensure_future(do_b(client))
await asyncio.gather(task1, task2)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(loop_a())
loop.close()
输出
CLIENT-1: doing a...
CLIENT-1: doing b...
CLIENT-1: a is done!
CLIENT-1: b is done!
CLIENT-2: doing a...
CLIENT-2: doing b...
CLIENT-2: a is done!
CLIENT-2: b is done!
CLIENT-3: doing a...
CLIENT-3: doing b...
CLIENT-3: a is done!
CLIENT-3: b is done!
CLIENT-4: doing a...
CLIENT-4: doing b...
CLIENT-4: a is done!
CLIENT-4: b is done!
CLIENT-5: doing a...
CLIENT-5: doing b...
CLIENT-5: a is done!
CLIENT-5: b is done!
编辑:
另一个问题。我如何让它不按照列表中的顺序执行?因为目前,CLIENT-1
正被 CLIENT-2
阻止,与其他客户端一样,我试图避免这种情况。这可能吗?
CLIENT-1: doing a...
CLIENT-2: doing a...
CLIENT-1: doing b...
CLIENT-3: doing a...
CLIENT-1: a is done!
CLIENT-1: b is done!
CLIENT-2: a is done!
CLIENT-3: a is done!
CLIENT-2: doing b...
CLIENT-2: b is done!
CLIENT-3: doing b...
CLIENT-3: b is done!
首先,这两个任务 不是 运行 同步的,从 doing b...
不断出现在 doing a...
和 a is done!
.
每对任务都在下一个客户开始之前完成,但那是因为您明确要求发生这种情况。如果您不想 await
每对,只需……不要 await
每对。例如:
futs = []
for client in clients:
futs.append(asyncio.ensure_future(do_a(client)))
futs.append(asyncio.ensure_future(do_b(client)))
await asyncio.gather(*futs)
a
和 b
同时 运行ning 并且输出显示了这一点。客户端 1、2、3、4 和 5 按顺序 运行ning 因为它们之间有一个 await asyncio.gather
。
您可以将所有任务合并到一个列表中,使它们同时 运行:
async def loop_a():
clients = ['CLIENT-1', 'CLIENT-2', 'CLIENT-3', 'CLIENT-4', 'CLIENT-5']
tasks = []
for client in clients:
tasks.append(asyncio.ensure_future(do_a(client)))
tasks.append(asyncio.ensure_future(do_b(client)))
await asyncio.gather(*tasks)
现在打印:
CLIENT-1: doing a...
CLIENT-1: doing b...
CLIENT-2: doing a...
CLIENT-2: doing b...
CLIENT-3: doing a...
CLIENT-3: doing b...
CLIENT-4: doing a...
CLIENT-4: doing b...
CLIENT-5: doing a...
CLIENT-5: doing b...
CLIENT-1: a is done!
CLIENT-2: a is done!
CLIENT-3: b is done!
CLIENT-1: b is done!
CLIENT-3: a is done!
CLIENT-2: b is done!
CLIENT-4: a is done!
CLIENT-5: b is done!
CLIENT-4: b is done!
CLIENT-5: a is done!