Python 使用协程构建并发应用

threading模块通过应用线程实现并发,multiprocessing使用进程实现并发。在python中,还有另外一种实现并发的方式,那就是协程——一种单线程单进程的方法来实现并发,通过asyncio模块可以实现。
使用asyncio并发执行任务有五种方式,分别是:

  • gather: 返回结果的顺序与传参顺序一致
  • wait:返回结果是一个元组,包含两个集合,已完成的任务和未完成的任务,支持timeout参数和return_when参数
  • create_task:创建的task可以通过cancel方法取消
  • ensure_future:在使用await之前,协程不会启动
  • as_completed: 创建生成器管理一个协程列表并生成他们的结果

下面将分别提供demo举例说明,假设我们要并发执行的任务如下:
模拟一个创建服务器连接的任务

import asyncio
	
async def get_connection(name):
    """模拟创建连接"""
    print(f'正在创建连接: {name} ...')
    await asyncio.sleep(1)  # 假设连接过程需要1秒,注意这里不能用time.sleep(),因为它不是异步函数
    print(f'{name} 创建成功!')
    return name

方式一:gather

async def coroutine1(count):
    """count: 并行任务的数量"""
    start = time.perf_counter()
    tasks = []
    for i in range(count):
        tasks.append(get_connection(f'conn{i}'))
    result = await asyncio.gather(*tasks)
    print('耗时', time.perf_counter() - start)
    return True

运行

if __name__ == '__main__':
    coro = coroutine1(5)
    values = asyncio.run(coro)
    print(values)

结果:

正在创建连接: conn0 ...
正在创建连接: conn1 ...
正在创建连接: conn2 ...
正在创建连接: conn3 ...
正在创建连接: conn4 ...
conn0 创建成功!
conn2 创建成功!
conn4 创建成功!
conn1 创建成功!
conn3 创建成功!
耗时 1.0077441999999999
['conn0', 'conn1', 'conn2', 'conn3', 'conn4']

方式二:wait

async def coroutine2(count):
    start = time.perf_counter()
    tasks = []
    for i in range(count):
        tasks.append(get_connection(f'conn{i}'))
    result = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
    print('耗时', time.perf_counter() - start)
    return result

运行方式同方式一,不再赘述
结果:

({<Task finished coro=<get_connection() done, defined at D:/PythonProjects/learnasyncio/learn_asyncio.py:69> result=True>, <Task finished coro=<get_connection() done, defined at D:/PythonProjects/learnasyncio/learn_asyncio.py:69> result=True>, <Task finished coro=<get_connection() done, defined at D:/PythonProjects/learnasyncio/learn_asyncio.py:69> result=True>, <Task finished coro=<get_connection() done, defined at D:/PythonProjects/learnasyncio/learn_asyncio.py:69> result=True>, <Task finished coro=<get_connection() done, defined at D:/PythonProjects/learnasyncio/learn_asyncio.py:69> result=True>}, set())

方式三:create_task

async def coroutine3(count):
    start = time.perf_counter()
    tasks = []
    for i in range(count):
        tasks.append(asyncio.create_task(get_connection(f'conn{i}')))
    for task in tasks:
        await task
    result = [task.result() for task in tasks]
    print('耗时', time.perf_counter() - start)
    return result

方式四:ensure_future

async def coroutine4(count):
    start = time.perf_counter()
    tasks = []
    for i in range(count):
        tasks.append(asyncio.ensure_future(get_connection(f'conn{i}')))
    for task in tasks:
        await task
    result = [task.result() for task in tasks]
    print('耗时', time.perf_counter() - start)
    return result

方式五:as_completed

async def coroutine5(count):

    tasks = [
        get_connection(f'conn{i}')
        for i in range(count)
    ]
    start = time.perf_counter()
    results = []
    for next_to_complete in asyncio.as_completed(tasks):
        result = await next_to_complete
        results.append(result)
    print('耗时', time.perf_counter() - start)
    return results
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值