develop
异步协程中的Event通知
Table of Contents
1. asyncio.Event是什么?
asyncio.Event 是 Python 异步编程中用于任务间同步的重要工具,它提供了一种简单的信号机制,允许一个或多个任务等待某个事件的发生。
核心概念
asyncio.Event 本质上是一个异步版本的 “开关” ,它有两种状态:
- 未设置(unset):初始状态,所有等待该事件的任务都会阻塞
- 已设置(set):事件被触发,所有等待的任务会被唤醒
主要方法
- Event() 构造方法,创建一个新的事件对象,初始状态为未设置。
- wait() 异步方法,调用后会阻塞当前任务,直到事件被设置(set() 被调用)。如果事件已经处于设置状态,调用后会立即返回。
- set() 将事件设置为 “已设置” 状态,唤醒所有正在等待该事件的任务。
- clear() 将事件重置为 “未设置” 状态,使后续的 wait() 调用再次阻塞,直到下一次 set() 被调用。
- 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. 结果说明
由结果可知:
- 主协程开始后,创建了一个用于2s后,触发worker协程的协程
- async_worker开始工作,直到event.wait()。因为该event处于未设置(unset),所以任务会被阻塞
- 同时主协程码可没有被阻塞住,2s后,执行event.set()。使得event处理被唤醒的状态,worker中的协程被唤醒,继续执行后续的代码
- 主协程也执行完毕
DEVELOP · ASYNCIO
develop python3 async coroutine
