事件循环工作原理
- 基本概念:事件循环是一个无限循环,它等待任务、回调函数或I/O操作等事件发生,然后按照一定规则执行相应的处理代码。
- 工作流程:
- 任务注册:将异步任务(如
async
函数包装成的Task
对象)注册到事件循环中。这些任务可以是I/O操作(如网络请求、文件读写)、定时任务等。
- 事件监控:事件循环持续监控所有注册任务相关的事件,例如,当一个Socket连接有数据可读时,就会产生一个可读事件。
- 任务调度:当事件发生时,事件循环从任务队列中挑选一个可执行的任务(通常基于FIFO或优先级等策略),将控制权交给该任务,执行其相关代码。执行完或该任务阻塞(如等待I/O完成)时,再切换到其他可执行任务。
在asyncio
库中创建和使用事件循环处理异步Socket操作
- 创建事件循环:
在Python中,可以使用
asyncio.get_event_loop()
来获取当前线程的事件循环对象。在Python 3.7及以上版本,还可以使用asyncio.run()
,它内部会创建并管理事件循环。
import asyncio
async def main():
# 这里写异步Socket操作代码
pass
if __name__ == "__main__":
asyncio.run(main())
- 使用事件循环处理异步Socket操作:
- 创建异步Socket:使用
asyncio.open_connection()
函数创建异步TCP连接,它返回一个包含reader
和writer
对象的元组。
async def client():
reader, writer = await asyncio.open_connection('127.0.0.1', 8888)
writer.write(b'Hello, server!')
await writer.drain()
data = await reader.read(100)
print(f"Received: {data.decode()}")
writer.close()
await writer.wait_closed()
- **注册任务到事件循环**:将异步函数包装成`Task`对象并添加到事件循环中执行。如上述代码,在`asyncio.run()`中传入`client()`函数,`asyncio.run()`会自动将其注册到内部创建的事件循环并执行。也可以手动获取事件循环并添加任务:
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(client())
finally:
loop.close()