Personal Blog

develop

异步协程中的Event通知

介绍python3中异步协程中的event通知的使用方法

1. asyncio.Event是什么?

asyncio.Event 是 Python 异步编程中用于任务间同步的重要工具,它提供了一种简单的信号机制,允许一个或多个任务等待某个事件的发生。

核心概念

asyncio.Event 本质上是一个异步版本的 “开关” ,它有两种状态:

  1. 未设置(unset):初始状态,所有等待该事件的任务都会阻塞
  2. 已设置(set):事件被触发,所有等待的任务会被唤醒

主要方法

  1. Event() 构造方法,创建一个新的事件对象,初始状态为未设置。
  2. wait() 异步方法,调用后会阻塞当前任务,直到事件被设置(set() 被调用)。如果事件已经处于设置状态,调用后会立即返回。
  3. set() 将事件设置为 “已设置” 状态,唤醒所有正在等待该事件的任务。
  4. clear() 将事件重置为 “未设置” 状态,使后续的 wait() 调用再次阻塞,直到下一次 set() 被调用。
  5. is_set() 返回布尔值,表示事件当前是否处于 “已设置” 状态。

2. 举个栗子来说明

event比较好理解,不需要太多的解释,直接上代码

import asyncio
import logging

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    datefmt='%H:%M:%S'
)

async def async_worker(event: asyncio.Event):
    logging.info("协程等待异步事件...")
    logging.info(f"event is set? {event.is_set()}")
    await event.wait()  # 异步等待,不阻塞事件循环
    logging.info(f"event is set? {event.is_set()}")
    logging.info("协程收到事件信号、处理任务并退出")
    

async def main():
    logging.info("主协程开始...")
    event = asyncio.Event()
    # 启动一个协程模拟"线程"设置事件
    async def set_event():
        await asyncio.sleep(2)  # 异步延迟
        event.set()
    
    asyncio.create_task(set_event())
    await async_worker(event)
    logging.info("主协程结束...")
    
asyncio.run(main())

Log输出如下:

17:09:07 - MainThread - INFO - 主协程开始...
17:09:07 - MainThread - INFO - 协程等待异步事件...
17:09:07 - MainThread - INFO - event is set? False
17:09:09 - MainThread - INFO - event is set? True
17:09:09 - MainThread - INFO - 协程收到事件信号、处理任务并退出
17:09:09 - MainThread - INFO - 主协程结束...

3. 结果说明

由结果可知:

  1. 主协程开始后,创建了一个用于2s后,触发worker协程的协程
  2. async_worker开始工作,直到event.wait()。因为该event处于未设置(unset),所以任务会被阻塞
  3. 同时主协程码可没有被阻塞住,2s后,执行event.set()。使得event处理被唤醒的状态,worker中的协程被唤醒,继续执行后续的代码
  4. 主协程也执行完毕

DEVELOP · ASYNCIO
develop python3 async coroutine