io select poll epoll 理解

本文详细介绍了计算机网络中的I/O模式,包括阻塞、非阻塞、IO多路复用等,并重点分析了Epoll的工作原理及其内部实现机制。通过对比select和poll,阐述了Epoll的优势和适用场景。




io 模式
read 操作发生时
1, 等待数据准备
2, 将数据冲内核拷贝到进程 
->由此产生的五种网络模式
1, 阻塞______
|___.同上
2, 非阻塞____
|___.用户进程需要不断的主动询问kernel数据好了没有。[ 有返回数据,没有返回error ,继续轮询 read ]
3, io多路复用
|___.select poll epoll会轮询所负责的所有socket,当某个socket数据到达了,就通知用户进程
4, 信号驱动io  (实际中不常用)
  5, 异步______
  |___.从kernel的角度,当它受到一个asynchronous read之后,首先它会立刻返回,所以不会对用户进程产生任何block。然后,
  |___.kernel会等待数据准备完成,然后将数据拷贝到用户内存,当这一切都完成之后,kernel会给用户进程发送一个signal,告诉它read操作完成了。








select poll epoll
select  
1024的限制 r + w + e 事件
poll
event 将要发生的事件 + revent 发生的事件 
epoll
____________________________________________________________________________________________________________________________________
mmap + rdr (red black root) + rdlist [ 文件fd状态改变,存储fd 对应的 epitem ]
epoll wait的工作流程:
(1) epoll_wait调用ep_poll,当rdlist为空(无就绪fd)时挂起当前进程,知道rdlist不空时进程才被唤醒。
(2) 文件fd状态改变(buffer由不可读变为可读或由不可写变为可写),导致相应fd上的回调函数ep_poll_callback()被调用。
(3) ep_poll_callback将相应fd对应epitem加入rdlist,导致rdlist不空,进程被唤醒,epoll_wait得以继续执行。
(4) ep_events_transfer函数将rdlist中的epitem拷贝到txlist中,并将rdlist清空。
(5) ep_send_events函数(很关键),它扫描txlist中的每个epitem,调用其关联fd对应的poll方法(图中蓝线)。
此时对poll的调用仅仅是取得fd上较新的events(防止之前events被更新),之后将取得的events和相应的fd发送到用户空间(封装在struct epoll_event,从epoll_wait返回)。
之后如果这个epitem对应的fd是LT模式监听且取得的events是用户所关心的,则将其重新加入回rdlist(图中蓝线),否则(ET模式)不在加入rdlist。
http://blog.chinaunix.net/uid-28541347-id-4273856.html
____________________________________________________________________________________________________________________________________
操作方法
EPOLL_CTL_ADD //新增
EPOLL_CTL_MOD //修改
EPOLL_CTL_DEL //删除
事件
EPOLLIN 表示对应的文件描述符可以读
EPOLLOUT 可以写
EPOLLPRI 有紧急的事件可以读
EPOLLERR 对应的文件描述符发生错误
EPOLLHUP 对应的文件描述符挂断
EPOLLET 将EPOLL 设置成边缘模式
EPOLLONESHOT 只监听一次,完后需要把socket再次加到EPOLL队列 
使用注意:
epoll并不是在所有的应用场景都会比select和poll高很多。
尤其是当活动连接比较多的时候,回调函数被触发得过于频繁的时候,epoll的效率也会受到显著影响!
所以,epoll特别适用于连接数量多,但活动连接较少的情况。




参考 
[ 初始参考 ] https://blog.youkuaiyun.com/u013679744/article/details/79188768
    [ 同步/异步 ] https://blog.youkuaiyun.com/scucscheng/article/details/51940552
[ 代码验证 ] https://www.cnblogs.com/lojunren/p/3856290.html
[ 深入内核 ] http://blog.chinaunix.net/uid-28541347-id-4273856.html
### 三种网络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 才能充分发挥硬件潜力达到最佳吞吐量效果。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值