springboot的城市化自修室管理系统设计开发实现
2026/1/18 17:23:18
想象你在经营一个快递驿站,顾客来取快递:
// 就像你每隔一段时间就问每个顾客:while(true){for(每个顾客){问:"有你的快递吗?"}// 处理有快递的顾客}特点:
// 顾客先填好表格放在桌上,你只需要检查表格structpoll{int顾客编号;short事件;// "有快递"、"要寄件"};while(true){扫描所有表格();// 扫描所有顾客的表格// 处理有事件的顾客}改进:
// 安装了一套智能系统:1.顾客进门先登记(epoll_ctl)2.有快递时,系统自动亮灯通知(epoll_wait只返回有事件的)3.你只需要处理亮灯的顾客// 系统还有两种工作模式:// LT模式:快递没取走,灯一直亮(反复通知)// ET模式:快递来了只闪一下灯,取不走就要自己负责| 特性 | Select | Poll | Epoll |
|---|---|---|---|
| 最大连接数 | 1024 | 无限制 | 无限制 |
| 工作效率 | O(n),每次都扫描所有 | O(n),扫描所有 | O(1),只通知有事件的 |
| 内存拷贝 | 每次都要复制所有fd | 每次都要复制所有fd | 只复制就绪的fd |
| 触发方式 | 水平触发 | 水平触发 | 水平/边缘触发 |
| 内核支持 | 所有系统 | 所有系统 | 仅Linux 2.6+ |
| 使用复杂度 | 简单 | 中等 | 较复杂 |
Select方式:
Poll方式:
Epoll方式:
// Select:查询1000个连接fd_set readfds;FD_ZERO(&readfds);for(i=0;i<1000;i++){FD_SET(fds[i],&readfds);// 所有连接加入集合}select(1001,&readfds,NULL,NULL,NULL);// 内核遍历1000个// 应用层再遍历1000个找就绪的// Poll:也是遍历1000个structpollfdfds[1000];poll(fds,1000,-1);// 内核遍历1000个// 应用层再遍历1000个// Epoll:只处理就绪的intepfd=epoll_create(1000);// 创建红黑树+就绪链表epoll_ctl(epfd,EPOLL_CTL_ADD,fd,&ev);// 注册到红黑树epoll_wait(epfd,events,1000,-1);// 只返回就绪的,可能就几个// 直接处理返回的几个events用户态 内核态 ↓ ↓ [1,2,3...1000] → 遍历所有 → [1,5,7] // 返回就绪的 ↑ ↑ 复制所有 复制就绪的用户态 内核态 ↓ ↓ 注册fd到红黑树 → 等待事件 → 就绪链表 ← 事件发生 ↑ ↑ 只复制就绪fd 只检查就绪链表就像从"挨家挨户敲门"进化到"手机智能推送",Epoll让服务器知道谁有事要处理,而不是盲目地问所有人有没有事。