Python 异步 协程 asyncio

1、介绍:

官网地址:asyncio --- 异步 I/O — Python 3.10.0 文档

asyncio 是用来编写 并发 代码的库,使用 async/await 语法。

asyncio 被用作多个提供高性能 Python 异步框架的基础,包括网络和网站服务,数据库连接库,分布式任务队列等等。

asyncio 往往是构建 IO 密集型和高层级 结构化 网络代码的最佳选择。

2、await

await 后面只能跟可等待对象。

可等待 对象有三种主要类型: 协程任务 和 Future.

2-1:协程

  • 协程函数: 定义形式为 async def 的函数;

  • 协程对象: 调用 协程函数 所返回的对象。

import asyncio


# 被async 修饰的函数叫做协程函数
async def test_demo():
    print('start')
    ...
    print('end')


# 调用协程函数所返回的对象,叫做协程对象
demo1 = test_demo()

2-2:任务

任务 被用来“并行的”调度协程

当一个协程通过 asyncio.create_task() 等函数被封装为一个 任务,该协程会被自动调度执行:

import asyncio

async def nested():
    return 42

async def main():
    # Schedule nested() to run soon concurrently
    # with "main()".
    task = asyncio.create_task(nested())

    # "task" can now be used to cancel "nested()", or
    # can simply be awaited to wait until it is complete:
    await task

asyncio.run(main())

2-3:future对象

表示一个异步操作的 最终结果

当一个 Future 对象 被等待,这意味着协程将保持等待直到该 Future 对象在其他地方操作完毕。

在 asyncio 中需要 Future 对象以便允许通过 async/await 使用基于回调的代码。

3、运行 asyncio.run(coro*debug=False)

此函数会运行传入的协程,负责管理 asyncio 事件循环,终结异步生成器,并关闭线程池。

当有其他 asyncio 事件循环在同一线程中运行时,此函数不能被调用。

如果 debug 为 True,事件循环将以调试模式运行。

此函数总是会创建一个新的事件循环并在结束时关闭之。它应当被用作 asyncio 程序的主入口点,理想情况下应当只被调用一次。

import asyncio


async def main():
    await asyncio.sleep(1)
    print('hello')

# python 3.7版本新增功能,但是我使用3.9.6版本使用此方法报错:RuntimeError: Event loop is closed
asyncio.run(main())
# python 3.5--end版本可使用以下方式
loop = asyncio.get_event_loop()
loop.run_until_complete(main())

4、创建协程任务:asyncio.create_task(coro*name=None)

将 coro 协程 封装为一个 Task 并调度其执行。返回 Task 对象。

name 不为 None,它将使用 Task.set_name() 来设为任务的名称。

import asyncio


async def coro():
    print('start')
    await ...
    print('end')


async def main():
    # 创建协程任务
    task1 = asyncio.create_task(coro())
    task1 = asyncio.create_task(coro())
    task_list = [task1, task2]

    await asyncio.wait(task_list)
    print('hello')


asyncio.run(main())

5、休眠 : asyncio.sleep(delayresult=None*loop=None)

阻塞 delay 指定的秒数。

如果指定了 result,则当协程完成时将其返回给调用者。

sleep() 总是会挂起当前任务,以允许其他任务运行。

将 delay 设为 0 将提供一个经优化的路径以允许其他任务运行。 这可供长期间运行的函数使用以避免在函数调用的全过程中阻塞事件循环。

import asyncio


async def coro():
    print('start')
    # 当前协程休眠一秒
    await asyncio.sleep(1)
    print('end')


async def main():
    # 创建协程任务
    task1 = asyncio.create_task(coro())
    task1 = asyncio.create_task(coro())
    task_list = [task1, task2]
    # 等待
    await asyncio.wait(task_list)
    print('hello')


asyncio.run(main())

6、简单等待 asyncio.wait

asyncio.wait(aws*loop=Nonetimeout=Nonereturn_when=ALL_COMPLETED)

并发地运行 aws 可迭代对象中的 可等待对象 并进入阻塞状态直到满足 return_when 所指定的条件。

aws 可迭代对象必须不为空。

返回两个 Task/Future 集合: (done, pending)

请注意此函数不会引发 asyncio.TimeoutError。当超时发生时,未完成的 Future 或 Task 将在指定秒数后被返回。

return_when 指定此函数应在何时返回。它必须为以下常数之一:

常数

描述

FIRST_COMPLETED

函数将在任意可等待对象结束或取消时返回。

FIRST_EXCEPTION

函数将在任意可等待对象因引发异常而结束时返回。当没有引发任何异常时它就相当于 ALL_COMPLETED

ALL_COMPLETED

函数将在所有可等待对象结束或取消时返回。

与 wait_for() 不同,wait() 在超时发生时不会取消可等待对象。

* python3.8版本,直接向 wait() 传入协程对象的方式已弃用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值