【Python】 async/await

【Python】 async/await

1. 前言

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

2. 进程、线程、协程

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

3. Pyhton中协程实现

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

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

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

python 复制代码
# 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())

运行结果:

text 复制代码
[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)

相关推荐
Scott9999HH3 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
AI云海4 小时前
python 列表、元组、集合和字典
开发语言·python
二十雨辰5 小时前
[爬虫]-Urllib
爬虫·python
玉鸯7 小时前
Agent Hook:在概率推理之上,为 Agent 叠加确定性控制
python·langchain·agent
weixin_446260857 小时前
HACO:面向动态部署环境的对冲式智能计算可靠多智能体调度框架
后端·python·flask
我的xiaodoujiao7 小时前
API 接口自动化测试详细图文教程学习系列32--Allure测试报告2
python·学习·测试工具·pytest
qetfw8 小时前
MXU:Tauri 2 + React 的 MaaFramework 跨平台 GUI 源码
前端·python·react.js·前端框架·开源项目·效率工具
用户8356290780518 小时前
Python 实现 Excel 页面布局与打印设置自动化
后端·python
一次旅行9 小时前
Python+大模型端到端自动化日报系统
开发语言·python·自动化