IO模型(select, poll, epoll的区别和原理)

参考《unix网络编程》

参考http://blog.csdn.net/blueboy2000/article/details/4485874

参考http://blog.csdn.net/suxinpingtao51/article/details/46314097


五种I/O模型

  1. 阻塞I/O:应用程序调用一个IO函数,导致应用程序阻塞,如果数据已经准备好,从内核拷贝到用户空间,否则一直等待下去

  2. 非阻塞I/O:

  3. I/O复用(select和poll)

  4. 信号驱动I/O(SIGIO)

  5. 异步I/O(Posix.1的aio_系列函数)

一个输入操作通常包括两个阶段:
### 三种网络IO模型的对比 #### Select `select` 是一种早期的多路复用机制,用于监控多个文件描述符的状态变化。它通过一个数组来管理这些文件描述符,并允许程序一次性查询它们是否有数据可读或写入是否可用。然而,它的性能存在瓶颈,因为每次调用 `select` 都会重新复制整个文件描述符集合到内核空间并逐一检查其状态[^1]。 优点: - 支持多种平台。 缺点: - 文件描述符的数量受限于系统定义的最大值(通常较小)。 - 效率低下,尤其是当监听大量连接时,因为它需要遍历所有句柄以找到已准备好的那些。 - 不适合大规模并发环境下的高性能需求。 ```c fd_set readfds; FD_ZERO(&readfds); FD_SET(fd, &readfds); if (select(max_fd + 1, &readfds, NULL, NULL, timeout)) { if(FD_ISSET(fd, &readfds)){ // 处理I/O事件... } } ``` #### Poll 相比 `select`, `poll` 解除了最大文件描述符数量限制的问题,但它仍然继承了类似的缺陷——即每次调用都需要传递完整的列表给内核去扫描每一个条目是否存在活动情况[^1]。 结构体形式使得它可以容纳更多的项而不受传统位掩码大小的影响: ```c struct pollfd fds[n]; for(i=0;i<n;i++) { fds[i].fd = some_file_descriptor(); fds[i].events = POLLIN | POLLOUT; } ret = poll(fds, n, timeout_ms); foreach i from 0 to ret{ process_event(fds[i]); } ``` 尽管如此,由于缺乏内部优化设计如红黑树索引等技术手段的支持,在面对极高频率访问请求或者超大容量链接池的情况下表现依旧不够理想。 #### Epoll 作为 Linux 特有的改进版本,`epoll` 提供了一套更加灵活高效的解决方案。主要体现在以下几个方面: - **分离操作**: 将注册感兴趣的事件与实际等待发生分开执行(`epoll_ctl()` `epoll_wait()`) ,从而减少了不必要的开销; - **无上限约束**: 关心的文件描述符数目理论上仅取决于系统的内存资源而非固定的数值界限; - **高效的数据结构运用**: 利用了诸如红黑树这样的高级算法加快查找速度的同时还借助双向链表存储就绪队列以便快速定位目标对象[^3]。 下面展示了一个简单的例子说明如何创建 epoll 实例并向其中添加新的 socket 连接以及轮询发生的 I/O 条件变更: ```c int efd = epoll_create1(0); struct epoll_event ev, events[MAX_EVENTS]; ev.events = EPOLLIN | EPOLLET; ev.data.fd = listen_sock; epoll_ctl(efd, EPOLL_CTL_ADD, listen_sock, &ev); while(true){ nfds = epoll_wait(efd, events, MAX_EVENTS, -1); for(n = 0; n < nfds; ++n){ handle_io(events[n].data.fd); } } ``` 综上所述,对于不同规模的应用场景可以选择合适的工具集来满足特定的要求。如果只是少量短时间内的交互,则可能 select 或者 basic blocking io 已经足够胜任;而对于大型服务器架构而言,采用 epoll 才能充分发挥硬件潜力达到最佳吞吐量效果。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值