linux i o源码,Linux I/O复用 —— epoll 部分源码剖析

epoll 相关的系统调用有以下三个,这里简述下当调用对应函数后,内核的具体实现

epoll_creat( )

1. 在内核注册文件系统 eventpollfs,挂载此文件系统

(linux一切皆文件,便于处理)

若返回指针,指针如果出错则无法判断,而 fd 可以通过 current -> files -> fd_array[] 找到其真伪

epoll_creat 为什么返回一个 fd?因为它对应的就是这个文件系统中创建的新文件

2. 创建两个内核 cache(频繁分配小块内存,应该创建 kmem_cahe 来做内存池),分别存放 struct epitem(事件信息) 和 eppoll_entry (用于挂在设备等待队列下)

创建struct eventpoll(红黑树根/就绪链表)结构,放入 file -> private data

(一个新创建的epoll文件带有一个struct eventpoll 结构,这个结构上再挂一个红黑树,而这个红黑树就是每次 epoll_ctl 时 fd 存放的地方)

epoll_ctl( )

1. 检测红黑树中有没有当前 fd 有则返回,没有则插入树中:

ep_insert( )

创建 struct eppoll_entry(为了放入设备等待队列)

设置其唤醒回调函数为 ep_poll_callback

加入设备等待队列 (设备驱动)

(当设备就绪,唤醒等待队列上的等待者时,ep_poll_callback就会被调用,将 epitem 放入 rdlist,每次调用 epoll_wait 就只收集 rdlist 里 的 fd 就可以了)

8586f2eb0e78582a991f3d982330715f.png

ET/LT 工作模式的区别

来自百度百科的解释:

LT(level triggered)是缺省的工作方式,并且同时支持block和no-block

socket.在这种做法中,内核告诉你一个文件描述符是否就绪了,然后你可以对这个就绪的fd进行IO操作。如果你不作任何操作,内核还是会继续通知你的,所以,这种模式编程出错误可能性要小一点。传统的select/poll都是这种模型的代表。

ET (edge-triggered)是高速工作方式,只支持non-block

socket。在这种模式下,当描述符从未就绪变为就绪时,内核通过epoll告诉你。然后它会假设你知道文件描述符已经就绪,并且不会再为那个文件描述符发送更多的就绪通知,直到你做了某些操作导致那个文件描述符不再为就绪状态了(比如,你在发送,接收或者接收请求,或者发送接收的数据少于一定量时导致了一个EWOULDBLOCK

错误)。但是请注意,如果一直不对这个fd作IO操作(从而导致它再次变成未就绪),内核不会发送更多的通知(only

once),不过在TCP协议中,ET模式的加速效用仍需要更多的benchmark确认。

ET和LT的区别就在这里体现,LT事件不会丢弃,而是只要读buffer里面有数据可以让用户读,则不断的通知你。而ET则只在事件发生之时通知。可以简单理解为LT是水平触发,而ET则为边缘触发。LT模式只要有事件未处理就会触发,而ET则只在高低电平变换时(即状态从1到0或者0到1)触发。

对应的具体实现如下

在内核中除了上面提到的就绪队列 rdlist 外,还另外维护了一个队列 txlist,用于内核空间与用户空间的缓冲

在 LT 模式下,当我们调用 epoll_wait() 时:

睡眠 & 检查 rdlist 是否为空

调用 ep_poll()

把 txlist 里的 fd 拷给用户空间,然后 ep_reinject_items 把一部分 fd 从 txlist 里返还给

rdlist 以便下次还能从 rdlist 中发现它 调用 ep_reinject_items()

将 txlist 中 没有标注 EPOLLET 且事件被关注的 fd 重新放回 rdlist,下一次 epoll_wait()

时会再次响应

ac428d8d71b450a8327123534e23c7c1.png

068be7e19a8fd7ea1cc73db7ddbb42c1.png

*夜空中最亮的星*

发布了1 篇原创文章 · 获赞 6 · 访问量 4301

私信

关注

标签:rdlist,epoll,源码,fd,内核,Linux,ET,就绪

来源: https://blog.csdn.net/weixin_38054045/article/details/103466891

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值