建设网站费用记入什么科目,软件开发分为哪几个步骤,乡镇府建设网站,wordpress用户列表文章目录 一、epoll初识
二、epoll的相关系统调用
1.epoll_create
2.epoll_ctl
3.epoll_wait
三、epoll工作原理
四、epoll的工作方式 本文主要介绍了epoll内部工作机制#xff0c;如何达到高性能的多路转接。技术有限#xff0c;如有错误请指正。参考文献#xff1a;… 文章目录 一、epoll初识
二、epoll的相关系统调用
1.epoll_create
2.epoll_ctl
3.epoll_wait
三、epoll工作原理
四、epoll的工作方式 本文主要介绍了epoll内部工作机制如何达到高性能的多路转接。技术有限如有错误请指正。参考文献深入揭秘 epoll 是如何实现 IO 多路复用的 一、epoll初识
按照man手册epoll是为处理大批量句柄而改进的poll被公认为linux2.6下性能最好的io就绪通知方法
二、epoll的相关系统调用
epoll有三个相关调用
1.epoll_create
int epoll_create(int size);创建一个epoll句柄从Linux2.6.8之后size参数是被忽略的设置为0即可。
用完之后必须调用close()关闭
2.epoll_ctl
int epoll_ctl(int epfd,int op,int fd,struct epoll_event *event);epoll的事件注册函数
它不同于select()是在监听事件时告诉内核要监听什么类型的事件而是在这里先注册要监听的事件类型epfd是创建的返回值第二个参数表示动作用三个宏来表示EPOLL_CTL_ADD注册新的fd到epfd中 EPOLL_CTL_MOD修改已经注册的fd监听事件 EPOLL_CTL_DEL从epfd中删除一个fd第三个参数是需要监听的fd第四个参数是告诉内核需要监听什么事件
struct epoll_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_data_t data;} __EPOLL_PACKED;
events可以是几个宏的集合 EPOLLIN:表示对应的fd可以读(包括对端SOCKET正常关闭)
EPOLLOUT:表示对应的fd可以写
EPOLLPRI:表示对应的fd有紧急的数据可读这里对应表示有带外数据到来
EPOLLERR:表示对应的fd描述符发生错误
EPOLLHUP:表示对应的fd被挂断
EPOLLET:将epoll设置为边缘触发et),这是相对于水平触发(lt)来说的
EPOLLONESHOT:只监听一次事件当监听完这次事件后如果还需要继续监听socket的话需要再次把这个socket加入到epoll队列中
3.epoll_wait
int epoll_wait(int epfd,struct epoll_event *events,int maxevents,int timeout);收集在epoll监控的事件中已经发送的事件
参数events是分配好的epll_event结构体数组epoll将会把发生的事件赋值到events数组中events不可以是空指针内核只负责把数据复制到这个events数组中不会去帮助我们在用户态中分配内存maxevents告知内核这个events有多大这个Maxevnets的值不能大于创建epoll_create()时的size参数timeout是超时事件ms,0会立即返回-1永久阻塞函数调用成功返回对应io上已经准备好的fd数目如返回0表示已经超时返回小于0表示函数失败
三、epoll工作原理
struct eventpoll
{/* 红黑树的根节点这棵树中存储着所有添加到epoll当中需要监控的事件*/struct rb_tree;struct list_head rdlist;
};每一个epoll对象都有一个独立的eventpoll结构体用于存放通过epoll_ctl方法向epoll对象中添加进来的事件
这些事件都会挂载在红黑树中如此重复添加的事件就可以通过红黑树而高效的识别出来红黑树的插入效率是logn,其中n为树的高度
而所有添加到epoll事件中都会与设备网卡驱动程序建立回调关系也就是说当响应的事件发生时都会调用这个回调方法
这个回调方法在内核中叫ep_poll_callback它会将发生的事件添加到rdlist双链表中
在epoll中对于每一个事件都会建立一个epitem结构体。
struct epitem
{struct rb_node rbn; //红黑树节点struct list_head rdllink; //双向链表节点struct epoll_filefd ffd; //事件句柄信息struct eventpoll *ep; //指向其所属的eventpoll对象struct epoll_event event; //期待发生的事件类型
}
当调用epoll_wait检查是否有事件发生时只需要检查eventpoll对象中的rdlist双链表中是否有epitem元素即可
如果rdlist不为空则把发生的事件复制到用户态同时将事件数量返回给用户这个操作的事件复杂度为O(1) epoll的优点 接口使用方便虽然拆分成了三个函数但是使用起来更高效不需要每次循环都设置关注的fd,也做到了输入输出参数分离数据拷贝轻量只在合适的时候调用EPOLL_CTL_ADD将fd拷贝到内核中这个操作并不频繁而select,poll每次都需要进行拷贝事件回调机制避免使用遍历而是使用回调函数的方式将就绪的fd结构加入到就绪队列中epoll_wait返回直接访问就绪队列就知道哪些fd就绪这个操作事件复杂度O1即使fd很多效率也不会收到影响没有数量限制文件描述符数目无上限 有的地方说epoll使用了内存映射机制内存映射机制是内核直接将就绪队列通过mmap的方式映射到用户态避免了拷贝内存这样的额外性能开销。这种说法是不准确的我们定义的struct epoll_evnet是我们在用户空间中分配好的内存势必还是需要将内核中的数据结构拷贝到这个用户空间的内存中的。
四、epoll的工作方式