【Python】 async/await

【Python】 async/await

1. 前言

最近在使用的PTB的API,里面会碰到Python协程的使用,记录个人对此的浅显理解。

2. 进程、线程、协程

  • 进程:由一个可执行程序以及该可执行程序执行过程中所需要的内存资源组成,每个进程有自己独立的内存管理,因此进程切换、通信需要消耗很大的资源。
  • 线程:组成同进程一样,但是所占用的资源相比进程更少;线程为进程中一段程序执行流。
  • 协程:微线程,所需的资源进一步减少。协程的切换由线程程序切换,资源损耗更小。
  • 进程和线程关系:进程为操作系统分配资源的最小单位,一个进程由一个或多个线程组成,对于一个进程中的多个线程,他们共享操作系统给该进程所分配内存资源。

3. Pyhton中协程实现

用到的关键字为async/await,这两个关键字搭配使用。

async声明一个函数为异步函数,异步函数的特点是在函数执行过程中遇到await关键字则挂起,去执行其他异步函数。

await用于暂定异步函数的执行(并发操作中,把程序控制器交给主程序,让其分配其他协程执行),其后面只能跟async修饰的异步函数或带有__await__属性的对象。

# This is a sample Python script.
import time
import asyncio


async def subtask(name,cost_time):
    await asyncio.sleep(cost_time)
    print('[{}] Current task is {}.'.format(time.time(), name))


async def task(name, cost_time):
    print('[{}] {} is starting.'.format(time.time(), name))
    time_start = time.time()
    await subtask(name, cost_time)
    time_end = time.time()
    print('[{}] {} is ending.'.format(time.time(), name, time_end - time_start))
    return '{} costs {}s'.format(name, time_end - time_start)


async def demo_1():
    print('[{}] Demo1 starts tasks ......'.format(time.time()))
    st = time.time()
    result1 = await task('Task 1', 3)
    result2 = await task('Task 2', 6)
    result3 = await task('Task 3', 2)
    et = time.time()
    print('\b----- result ----')
    print('Total task cost {}s.'.format(et - st))
    print(result1)
    print(result2)
    print(result3)
    print()


async def demo_2():
    print('[{}] Demo2 starts tasks ......'.format(time.time()))
    st = time.time()
    result = await asyncio.gather(
        task('Task 1', 3),
        task('Task 2', 6),
        task('Task 3', 2),
    )
    et = time.time()
    print('\b----- result ----')
    print('Total task cost {}s.'.format(et - st))
    for item in result:
        print(item)
    print()


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    asyncio.run(demo_1())
    asyncio.run(demo_2())

运行结果:

[1709704883.4558887] Demo1 starts tasks ......
[1709704883.4558887] Task 1 is starting.
[1709704886.4710522] Current task is Task 1.
[1709704886.4710522] Task 1 is ending.
[1709704886.4710522] Task 2 is starting.
[1709704892.4716516] Current task is Task 2.
[1709704892.4716516] Task 2 is ending.
[1709704892.4716516] Task 3 is starting.
[1709704894.4731288] Current task is Task 3.
[1709704894.4731288] Task 3 is ending.
----- result ----
Total task cost 11.017240047454834s.
Task 1 costs 3.0151634216308594s
Task 2 costs 6.000599384307861s
Task 3 costs 2.0014772415161133s

[1709704894.475127] Demo2 starts tasks ......
[1709704894.475127] Task 1 is starting.
[1709704894.475127] Task 2 is starting.
[1709704894.475127] Task 3 is starting.
[1709704896.4786284] Current task is Task 3.
[1709704896.4786284] Task 3 is ending.
[1709704897.4788241] Current task is Task 1.
[1709704897.4788241] Task 1 is ending.
[1709704900.4797897] Current task is Task 2.
[1709704900.4797897] Task 2 is ending.
----- result ----
Total task cost 6.004662752151489s.
Task 1 costs 3.003697156906128s
Task 2 costs 6.004662752151489s
Task 3 costs 2.0035014152526855s

async声明的函数为一部函数,其需要在时间循环中调用,若向普通函数调用异步函数,未能体现其异步特征,如同Demo_1。asyncio.run()函数负责运行主体函数,并管理事件循环。asyncio.gather()可以并发多个异步函数。调用Demo_2,Task1、Task2、Task3同时执行,执行Task1的过程中遇到await则挂起Task1,去执行Task2,Task2遇到await则挂起,asyncio.gather()会在3个任务之间进行调度。

参考

[1] 理解Python协程(Coroutine)

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值