Skip to content

2. 异步编程

事件循环

事件循环(Event Loop)是异步编程的核心机制,可以理解为一个死循环,去检测并执行某些代码。

事件循环的工作原理可以用以下伪代码来描述:

text
# 伪代码

任务列表 = [ 任务1, 任务2, 任务3,... ]

while True:
    可执行的任务列表, 已完成的任务列表 = 去任务列表中检查所有的任务,将'可执行'和'已完成'的任务返回

    for 就绪任务 in 可执行的任务列表:
        执行已就绪的任务

    for 已完成的任务 in 已完成的任务列表:
        在任务列表中移除 已完成的任务

    如果 任务列表 中的任务都已完成,则终止循环
python
import asyncio

# 去生成一个事件循环
loop = asyncio.get_event_loop()
# 将任务放进任务列表,让事件循环去检测任务状态
loop.run_until_complete()

快速上手

协程函数,定义函数时候 async def,调用函数时候 await。 协程对象,执行 协程函数() 返回的对象。

python
# 定义协程函数
async def func():
    pass


# 获取协程对象
result = func()

注意:执行协程函数创建协程对象时,并不会立即执行函数体内的代码,只有在事件循环中运行该协程对象时,函数体内的代码才会被执行。

python
import asyncio


async def func():
    print("Start func")


result = func()

# loop = asyncio.get_event_loop()
# loop.run_until_complete(result)

asyncio.run(result)  # Python 3.7 及以上版本推荐使用, 代替上面两行代码

await

await + 可等待的对象(协程对象、Future、Task 对象 -> IO 等待)

python
import asyncio


async def others():
    print("  [others] Start others")
    await asyncio.sleep(1)  # 遇到IO,会切换去执行其他任务
    print("  [others] End others")
    return "Result from others"


async def func():
    print("[func] Start func")
    await asyncio.sleep(2)  # 遇到IO,会切换去执行其他任务
    print("[func] End func")
    return "Result from func"


async def main():
    # 创建task对象,将当前执行的函数func()和others()加入事件循环中
    task1 = asyncio.create_task(func())
    task2 = asyncio.create_task(others())

    # 等待两个任务完成
    result1 = await task1
    result2 = await task2

    print(f"\n结果: {result1}, {result2}")


asyncio.run(main())

# 执行顺序:
# 1. [func] Start func -> 遇到 sleep(2),切换到 task2
# 2. [others] Start others -> 遇到 sleep(1),切换
# 3. 1秒后 others 的 sleep 完成 -> [others] End others
# 4. 2秒后 func 的 sleep 完成 -> [func] End func

# 最后输出结果:
# [func] Start func
# [others] Start others
# [others] End others
# [func] End func

# 结果: Result from func, Result from others

task 对象

Tasks 用于并发调度协程,通过 asyncio.create_task(协程对象) 的方式创建 Task 对象,这样可以让协程加入到事件循环中进行调度执行。

白话:在事件循环中添加多个任务

python
import asyncio


async def func():
    print("Start func")
    await asyncio.sleep(1)
    print("End func")
    return "Result from func"


async def main():
    print("Creating task...")

    task_list = [
        asyncio.create_task(func(), name="n1"),
        asyncio.create_task(func(), name="n2"),
    ]

    print("Tasks created, waiting for results...")

    done, pending = await asyncio.wait(task_list)
    print(done)


asyncio.run(main())
python
import asyncio


async def func():
    print("Start func")
    await asyncio.sleep(1)
    print("End func")
    return "Result from func"


task_list = [
    func(),
    func(),
]

done, pending = asyncio.run(asyncio.wait(task_list))
print(done)

asyncio.Future 对象

task 对象是继承Future对象,task对象内部await结果的处理基于Future对象来实现的。

concurrent.futures.Future 对象

使用线程池、进程池实现异步操作时用到的对象。

异步迭代器

异步上下文管理器

此种对象通过定义 __aenter____aexit__ 方法来对 async with 语句中的环境进行控制。

python
import asyncio


class AsyncContextManager:
    async def __init__(self):
        pass

    async def do_something(self):
        print("Doing something asynchronously")

    async def __aenter__(self):
        # 操作之前先打开
        print("Entering async context")
        return self

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        # 操作之后再关闭
        print("Exiting async context")


async def main():
    # async with 必须放在协程函数内, manager 是__aenter__返回的对象
    async with AsyncContextManager() as manager:
        result = await manager.do_something()
        print(result)


asyncio.run(main())

构建时间:11/21/2025, 1:28:39 PM | 本博客内容均为自己学习,如内容涉及侵权,请联系邮箱:pangzl0215@163.com