繁体   English   中英

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-1CLIENT-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!之间不断出现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)

ab同时运行,输出显示。 客户端1、2、3、4和5依次运行,因为它们之间有一个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!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM