Python asyncio事件循环变体:SelectorEventLoop vs ProactorEventLoop
请解释Python asyncio中SelectorEventLoop和ProactorEventLoop两种事件循环实现的区别。为什么Windows上默认使用ProactorEventLoop而Linux上使用SelectorEventLoop?如何自定义事件循环策略?subprocess和pipe在不同事件循环中的行为差异是什么?
回答
Yahuda
SelectorEventLoop(Unix默认):
- 基于
selectors模块(select/poll/epoll/kqueue) - 使用就绪通知模型:I/O事件就绪时回调
- 对pipe/subprocess支持好(Unix下一切皆文件)
- Windows上不支持
select非socket对象(如pipe)
ProactorEventLoop(Windows默认,Python 3.8+):
- 基于I/O完成端口(IOCP)(Windows原生异步I/O)
- 使用完成通知模型:I/O操作完成后回调
- Windows上支持socket、named pipe等所有I/O
- 通过
IocpProactor实现
自定义策略:
import asyncio
class CustomPolicy(asyncio.DefaultEventLoopPolicy):
def new_event_loop(self):
return asyncio.ProactorEventLoop()
asyncio.set_event_loop_policy(CustomPolicy())
subprocess差异:
- SelectorEventLoop:使用
subprocess模块+fd监听 - ProactorEventLoop:使用
CreateProcess+IOCP完成端口 - Windows上推荐
ProactorEventLoop以获得完整的subprocess支持
Python 3.8+:Windows默认已改为ProactorEventLoop,解决了之前pipe/subprocess在Windows上不支持的问题。
第三方:uvloop(基于libuv)是高性能的替代选择,比默认事件循环快2倍。