epoll的实现机制¶
总图¶
accept创建新的socket¶
初始化socket对象¶
为新的socket申请file¶
接收连接,添加新文件到当前打开文件列表中¶
epoll_create的实现¶
创建eventpoll¶
关联到当前进程的打开文件列表中¶
epoll_ctl¶
这里以添加为例:
在使用 epoll_ctl 注册每一个 socket 的时候,内核会做如下三件事情
1. 分配一个红黑树节点对象 epitem
2. 添加等待事件到 socket 的等待队列中,其回调函数是 ep_poll_callback
3. 将 epitem 插入到 epoll 对象的红黑树里
初始化epitem¶
对于每一个 socket,调用 epoll_ctl 的时候,都会为之分配一个 epitem
设置socket等待队列¶
将epitem插入到红黑树中¶
epoll_wait¶
- 判断就绪队列中是否有就绪事件
- 假设确实没有就绪的连接,定义等待事件,并把 current (当前进程)添加到 waitqueue 上
- 添加到等待队列
- 当前线程主动让出CPU进入睡眠状态,选择下一个进程调度
data come¶
接收数据到等待队列¶
查找就绪队列中的回调函数¶
执行回调函数¶
执行socket就绪通知¶
总结¶
- epoll_create创建eventpoll
- epoll_ctl(添加)添加socket创建epitem插入到红黑树中
- epoll_wait检查就绪队列中是否有就绪事件,如果没有则将当前线程添加到等待队列中并主动让出CPU进入睡眠
- 数据包到达网卡,软中断执行接收数据到接收队列(socket)
- 插入epoll就绪队列
- 检查是否有线程阻塞
- 唤醒用户线程,返回事件