Epoll
epoll - I/O event notification facility
介绍
通常来说,实现处理tcp请求,为一个连接一个线程,在高并发的场景,这种多线程模型与Epoll相比就显得相形见绌了。epoll
是linux2.6内核的一个新的系统调用,epoll
在设计之初,就是为了替代select, poll
线性复杂度的模型,epoll的时间复杂度为O(1), 也就意味着,epoll
在高并发场景,随着文件描述符的增长,有良好的可扩展性。
select
和poll
监听文件描述符list,进行一个线性的查找 O(n)epoll
: 使用了内核文件级别的回调机制O(1)
下图展示了文件描述符的量级和CPU耗时
/proc/sys/fs/epoll/max_user_watches
表示用户能注册到epoll
实例中的最大文件描述符的数量限制。
关键函数
epoll_create1
: 创建一个epoll实例,文件描述符epoll_ctl
: 将监听的文件描述符添加到epoll实例中,实例代码为将标准输入文件描述符添加到epoll中epoll_wait
: 等待epoll事件从epoll实例中发生, 并返回事件以及对应文件描述符l
epoll 关键的核心数据结构如下:
typedef union epoll_data
{
void *ptr;
int fd;
uint32_t u32;
uint64_t u64;
} epoll_data_t;
struct epoll_event
{
uint32_t events; /* Epoll events */
epoll_data_t data; /* User data variable */
};
边沿触发vs水平触发
epoll
事件有两种模型,边沿触发:edge-triggered (ET), 水平触发:level-triggered (LT)
水平触发(level-triggered)
- socket接收缓冲区不为空 有数据可读