
Python epoll 完整详解功能、安装、语法、8大案例、错误与注意事项epoll是Linux 内核特有的高性能 I/O 多路复用机制Windows/macOS 不支持是 Python 实现高并发网络编程如百万级连接服务器的核心技术替代传统的select/poll解决了传统多路复用效率低、连接数受限的问题。Python 中通过内置标准库select实现 epoll 功能无需额外安装第三方包直接导入使用。一、epoll 核心功能与优势1. 核心功能监听大量文件描述符socket、管道、文件等的 I/O 事件可读、可写、异常仅主动通知就绪的文件描述符无需轮询全部描述符支持水平触发LT和边缘触发ET两种工作模式无最大连接数限制仅受系统内存限制2. 核心优势特性select/pollepoll效率O(n) 轮询所有描述符O(1) 仅通知就绪描述符连接数有限制默认1024无上限百万级连接内存拷贝每次都需拷贝描述符列表内核与用户空间共享内存适用场景低并发高并发、长连接二、安装说明Python 的select标准库内置 epoll 实现无需 pip 安装直接使用importselect环境要求操作系统Linux 2.6 内核CentOS、Ubuntu、Debian 等Python 版本Python 2.6 / Python 3.x全版本支持禁止使用Windows、macOS这两个系统用 kqueue/select 替代三、epoll 语法、核心方法与参数1. 创建 epoll 对象importselect# 创建 epoll 实例epollselect.epoll()2. 核心方法与参数详解方法语法参数说明功能register()epoll.register(fd, event_mask)fd文件描述符整数event_mask监听事件注册描述符到 epollunregister()epoll.unregister(fd)fd已注册的描述符注销描述符modify()epoll.modify(fd, event_mask)同 register修改监听事件poll()epoll.poll(timeout-1)timeout超时时间秒-1永久阻塞0非阻塞0超时时间等待就绪事件返回[(fd, event), ...]close()epoll.close()无参数关闭 epoll 对象3. 监听事件常量必须掌握# 1. 基础事件select.EPOLLIN# 可读事件有数据到来select.EPOLLOUT# 可写事件可以发送数据select.EPOLLERR# 错误事件select.EPOLLHUP# 连接断开事件# 2. 触发模式核心select.EPOLLET# 边缘触发ETselect.EPOLLPRI# 紧急数据可读4. 两种触发模式关键区别水平触发LT默认只要描述符有数据/可写持续通知编程简单不易丢数据边缘触发ET高性能模式仅在状态变化时通知一次如数据从无到有必须一次性读完所有数据否则会丢失事件性能更高适合超高并发四、8个实际应用案例可直接运行所有案例基于Linux 环境使用 Python3 运行。案例1基础 epoll 监听标准输入入门监听终端输入有数据时打印理解 epoll 基础用法。importselectimportsys# 1. 创建epoll对象epselect.epoll()# 2. 注册标准输入fd0监听可读事件ep.register(sys.stdin.fileno(),select.EPOLLIN)print(请输入内容输入 exit 退出)whileTrue:# 3. 等待就绪事件eventsep.poll()forfd,eventinevents:iffdsys.stdin.fileno():# 读取输入datasys.stdin.readline().strip()ifdataexit:ep.unregister(fd)ep.close()print(退出程序)exit()print(f你输入了{data})案例2高并发 TCP 服务器核心案例epoll 最经典用法支持上万并发连接的 TCP 服务器。importsocketimportselect# 1. 创建TCP socketserver_socketsocket.socket(socket.AF_INET,socket.SOCK_STREAM)server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)server_socket.bind((0.0.0.0,8888))server_socket.listen(10000)server_socket.setblocking(False)# 非阻塞# 2. 初始化epollepselect.epoll()ep.register(server_socket.fileno(),select.EPOLLIN)# 监听服务端socket# 存储连接key文件描述符value客户端socketconnections{}print(epoll TCP 服务器启动端口 8888)whileTrue:# 轮询就绪事件eventsep.poll()forfd,eventinevents:# 1. 服务端socket就绪新客户端连接iffdserver_socket.fileno():client_socket,addrserver_socket.accept()client_socket.setblocking(False)# 注册客户端socket监听可读事件ep.register(client_socket.fileno(),select.EPOLLIN)connections[client_socket.fileno()]client_socketprint(f新连接{addr})# 2. 客户端socket有数据可读elifeventselect.EPOLLIN:client_socketconnections[fd]try:dataclient_socket.recv(1024)ifdata:print(f收到数据{data.decode()})# 注册可写事件准备回复数据ep.modify(fd,select.EPOLLOUT)else:# 客户端断开ep.unregister(fd)client_socket.close()delconnections[fd]exceptExceptionase:ep.unregister(fd)client_socket.close()delconnections[fd]# 3. 客户端socket可写发送回复elifeventselect.EPOLLOUT:client_socketconnections[fd]client_socket.send(已收到你的消息.encode())# 改回监听可读事件ep.modify(fd,select.EPOLLIN)案例3边缘触发ET模式 TCP 服务器高性能 ET 模式必须一次性读完所有数据。# 仅需修改注册事件添加 EPOLLETep.register(server_socket.fileno(),select.EPOLLIN|select.EPOLLET)# 客户端数据读取时必须循环读满缓冲区databwhileTrue:try:chunkclient_socket.recv(1024)ifnotchunk:breakdatachunkexceptBlockingIOError:# 无数据可读ET模式下退出循环break案例4epoll 监听多个 socket多端口服务同时监听 8888、9999 两个端口的连接请求。importsocketimportselect# 创建两个服务端sockets1socket.socket()s1.bind((0.0.0.0,8888))s1.listen(5)s1.setblocking(False)s2socket.socket()s2.bind((0.0.0.0,9999))s2.listen(5)s2.setblocking(False)epselect.epoll()ep.register(s1.fileno(),select.EPOLLIN)ep.register(s2.fileno(),select.EPOLLIN)print(监听 8888 和 9999 端口)whileTrue:forfd,_inep.poll():iffds1.fileno():conn,addrs1.accept()print(f8888端口新连接{addr})iffds2.fileno():conn,addrs2.accept()print(f9999端口新连接{addr})案例5epoll 实现文件异步读取监听文件描述符文件有更新时自动读取。importselectimportos# 打开文件获取文件描述符fileopen(test.txt,r)fdfile.fileno()epselect.epoll()ep.register(fd,select.EPOLLIN)print(监听文件 test.txt 变化...)whileTrue:eventsep.poll()for_,_inevents:file.seek(0)# 移动到文件开头contentfile.read()print(文件内容\n,content)案例6epoll 管道进程间通信父子进程通过管道通信epoll 监听管道数据。importosimportselect# 创建管道r_fd,w_fdos.pipe()pidos.fork()ifpid0:# 子进程写入数据os.close(r_fd)foriinrange(3):os.write(w_fd,f子进程消息{i}.encode())os.close(w_fd)else:# 父进程epoll监听管道读取os.close(w_fd)epselect.epoll()ep.register(r_fd,select.EPOLLIN)for_,_inep.poll():dataos.read(r_fd,1024)print(父进程收到,data.decode())os.close(r_fd)案例7epoll 实现 UDP 高并发服务器UDP 无连接epoll 监听数据报到来。importsocketimportselect udp_socketsocket.socket(socket.AF_INET,socket.SOCK_DGRAM)udp_socket.bind((0.0.0.0,8888))udp_socket.setblocking(False)epselect.epoll()ep.register(udp_socket.fileno(),select.EPOLLIN)print(UDP 服务器启动)whileTrue:forfd,_inep.poll():data,addrudp_socket.recvfrom(1024)print(f来自{addr}{data.decode()})udp_socket.sendto(bUDP 已收到,addr)案例8优雅关闭 epoll 服务器处理信号安全关闭服务器、注销描述符。importsignalimportsocketimportselect server_socketsocket.socket()server_socket.bind((0.0.0.0,8888))server_socket.listen(5)server_socket.setblocking(False)epselect.epoll()ep.register(server_socket.fileno(),select.EPOLLIN)# 信号处理CtrlC 关闭服务器defclose_server(signum,frame):print(\n正在关闭服务器...)ep.unregister(server_socket.fileno())ep.close()server_socket.close()exit(0)signal.signal(signal.SIGINT,close_server)whileTrue:eventsep.poll()# 处理连接逻辑...五、常见错误与解决方案1.AttributeError: module select has no attribute epoll原因在 Windows/macOS 上运行 epoll解决方案仅在 Linux 系统运行或用selectors库跨平台2.OSError: [Errno 9] Bad file descriptor原因注册了已关闭的文件描述符重复注销描述符解决方案先关闭 socket再注销 epoll避免重复操作3.BlockingIOError: [Errno 11] Resource temporarily unavailable原因ET 模式下未一次性读完数据或非阻塞 socket 无数据解决方案ET 模式循环读取直到抛出该异常4. 高并发下服务器卡死原因使用了水平触发阻塞 socket解决方案所有 socket 必须设置setblocking(False)5. 客户端断开连接报错原因未处理EPOLLHUP断开事件解决方案监听EPOLLIN | EPOLLHUP | EPOLLERR六、使用注意事项避坑指南仅 Linux 可用开发时建议用 Linux 虚拟机/云服务器必须非阻塞所有注册到 epoll 的 socket/文件必须设置非阻塞模式ET 模式必须读满边缘触发下必须循环读取直到无数据及时注销描述符客户端断开后必须调用unregister()否则内存泄漏事件组合使用同时监听EPOLLIN | EPOLLHUP | EPOLLERR处理异常避免频繁 modify减少epoll.modify()调用提升性能最大打开文件限制高并发需修改系统参数ulimit -n 1000000优先用 selectors 库Python 官方推荐selectors.DefaultSelector()自动适配 epoll/kqueue/select跨平台更简单总结epoll 是 Linux 高并发核心Python 内置select库实现无需安装核心用法创建对象 → 注册描述符 → 轮询事件 → 处理读写两种模式水平触发简单、边缘触发高性能应用场景TCP/UDP 高并发服务器、进程间通信、文件监听关键避坑非阻塞模式、及时注销描述符、ET 模式读满数据《动手学PyTorch建模与应用:从深度学习到大模型》是一本从零基础上手深度学习和大模型的PyTorch实战指南。全书共11章前6章涵盖深度学习基础包括张量运算、神经网络原理、数据预处理及卷积神经网络等后5章进阶探讨图像、文本、音频建模技术并结合Transformer架构解析大语言模型的开发实践。书中通过房价预测、图像分类等案例讲解模型构建方法每章附有动手练习题帮助读者巩固实战能力。内容兼顾数学原理与工程实现适配PyTorch框架最新技术发展趋势。