在-Linux-下,服务器如何知道某个-TCP-连接来了消息-这就涉及-IO-事件通知机制
目录
在 Linux 下,服务器如何知道某个 TCP 连接来了消息? 这就涉及 IO 事件通知机制!
1. 阻塞 read()
- 阻塞
read()
就像 你打电话问饭好了吗,但如果对方不接电话(没数据),你就一直守在电话边等,什么别的事情都做不了 。
你打电话问外卖员“饭好了吗?”,如果外卖还没送到, 你只能一直等着,啥都干不了 。
(阻塞式等待)
- 优点 :实现简单,适用于单个连接。
- 缺点 :等待期间 CPU 无法做别的事, 如果有多个连接,性能极差 。
2. 轮询 read()
- **非阻塞
read()
- 轮询** 就是 你每秒钟打一次电话问“饭好了吗?” ,如果没好就挂断,等 1 秒再打一次,重复操作,浪费时间和精力。
你每秒钟打一次电话问“饭好了吗?”
如果没好,就挂断,过 1 秒再打一次 ,一直循环到饭做好。
(非阻塞 + 轮询)
- 优点 :不会完全卡住,但 CPU 仍然会被轮询占用。
- 缺点
:
即使没有饭做好,你还是要不停地打电话(轮询
read()
),CPU 资源浪费严重 。
3. select()
/ poll()
你在餐厅前台登记了一个电话,并告诉服务员:
“有饭做好了,打电话通知我。”
服务员真的通知你了,但他说:
“有几道菜做好了,你自己去检查是哪道菜。”
(你必须自己挨个检查)
- 优点 :不用一直打电话(轮询),CPU 资源消耗减少。
- 缺点 : 仍然要遍历所有连接(菜品)检查哪些是好的,连接数量大时很慢 。
4. epoll()
你用高科技 GPS 追踪器,每道菜都装上一个传感器, 只要菜做好了,GPS 直接告诉你“5 号菜、8 号菜已经完成!”
你不用自己挨个检查,而是直接处理完成的菜品。
- 优点 :只有有数据的连接才会被通知,不用遍历所有 socket, 处理速度是 O(1) 。
- 缺点
:Linux 独有,Windows 不支持(Windows 用
IOCP
代替epoll
)。
最终结论
方式 | 比喻 | 效率 |
---|---|---|
阻塞 read() | 你打电话问饭好了吗?没人接就一直等 | 低,卡住 CPU |
轮询 read() | 你每秒打一次电话问“饭好了吗?” | 很低,CPU 白白浪费 |
select() / poll() | 你让服务员通知你,但仍然要自己检查每道菜 | 中等,仍然要遍历所有连接 |
epoll() | 你用 GPS 追踪,服务员直接告诉你哪道菜好了 | 高效,适用于大规模高并发 |
所以,在写高性能 HTTP 服务器时,
epoll
是最佳选择。