本章主要介绍 epoll 的基础知识,其他细节已经上一篇文章中说明。
注:内容来自 https://mp.weixin.qq.com/s/OmRdUgO1guMX76EdZn11UQ
EPOLL 数据结构
eventpool
wait_queue_head_t wq | 等待队列链表。软中断数据就绪的时候会通过 wq 来找到阻塞在 epoll 对象上的用户进程。 |
struct list_head rdllist | 就绪的描述符链接。当有的连接就绪的时候,内核会把就绪的连接放到 rdlist 链表里。这样应用进程只需要判断链表就能找出就绪进程。而不用遍历整棵树。 |
struct rb_root rbr | 一颗红黑树。为了支持对海量连接的高效查询、插入和删除。eventpoll 内部使用了一颗红黑树。通过这颗树来管理用户进程下添加的所有 socket 连接。 |
.... |
epitem
struct rb_node rbn | 红黑树节点 |
struct epoll_filefd ffd | socket 文件描述符信息 |
struct eventpoll *ep | 所归属的 eventpoll 对象 |
struct list_head pwqlist | 等待队列 |
.... |
epoll 操作说明
epoll_create
在用户进程调用 epoll_create 时,内核会创建一个 struct eventpoll 的内核对象。并同样把它关联到当前进程的已打开文件列表中。
epoll_ctl
向 epoll 对象中添加要管理的连接,主要做三件事情:
1.分配一个红黑树节点对象 epitem。
2.添加等待事件到 socket 的等待队列中,其调回函数是 ep_poll_callback(这里的等待队列不是 eventpoll得,是 socke t的)。
3.将epitem 插入到epoll对象的红黑树里。
epoll_wait
epoll_wait 做的事情不复杂,当它被调用时观察 eventpoll->rdllist 链表里有没有数据即可。如果有数据就返回,没有数据就创建一个等待队列项,将其添加到 eventpoll 的等待队列上。然后把自己阻塞完事。