一直以来都不太喜欢写技术类日志,总感觉没什么好些,看了那么大牛的建议都说要建立一个自己的技术blog,对自己所学知识进行总结归纳,才更有利于自身的提高,今天就写下这第一篇技术文章吧。水平再差,总得有个开始吧。。。
epoll是linux下I/O多路复用的一种模型,貌似2.6内核以上才开始支持,以前一直是select/poll。
相对于select优势很明显,select能容纳的文件描述符最大为1024个,而且因为其内部是采用轮循的方式遍历描述符,所以效率会随着描述符的增加而降低,epoll则没有描述符的限制并且不会随着监听描述符的增加而降低效率
epoll操作也不难,总共3个函数:
1. int epoll_create (int size);
创建一个epoll的文件描述符,size表示监听描述符的最大数目
2. int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
对epoll进行操作,这个函数参数稍显负责。
epfd为epoll描述符
op为所做的操作,有一下几种方式:
EPOLL_CTL_ADD: 注册一个描述符
EPOLL_CTL_DEL: 删除一个描述符
EPOLL_CTL_MOD: 修改一个已注册描述符的监听事件
fd为操作的文件描述符
event为描述符对应的事件结构体:
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 */
};
其中主要变量events有几种组合:
EPOLLIN: 文件描述符可读
EPOLLOUT: 描述符可写
EPOLLPRI: 有紧急数据可读
EPOLLERR: 描述符出错
EPOLLHUP: 描述被关闭
EPOLLET: 设置为边缘模式(后面会简单说下边缘模式与水平模式区别)
EPOLLONESHOT: 只监听一次事件
这些宏可通过 | 符号来组合,如 EPOLLIN | EPOLLOUT
3. int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);
等待事件到来。
epfd: epoll描述符
events: 所有待处理的事件都会被放入该结构数组里
maxevents: events数组的大小
timeout: 超时时间
最后简单说下边缘模式与水平模式的区别:
ET(边缘模式)为高速模式,监听的描述符必须为非阻塞的,当描述符上有事件发生,它只通知一次,无论你处理该事件与否,它会默认你已经处理
LT(水平模式)监听描述符可以为阻塞或者非阻塞,当有事件发生,你没处理,它下次仍然会通知你继续处理该事件,直到你处理为止,这样减少了编程的出错率
哎。。。看来写技术文章真不容易,要花不少时间啊,才能完成一篇