相信大家用Socket肯定就会用到epoll机制,面对大量的连接,我们用传统的select等方式显得效率不高,具体请见下链接。
https://blog.youkuaiyun.com/wendy_keeping/article/details/76682861
epoll机制主要由三个函数组成epoll_create,epoll_ctl,epoll_wait,它就像一个请求池,我们的各个连接或数据传递,都放在这个池子里面,谁需要站出来服务,谁就站出来,并不需要像select一样遍历来找到底是谁(其中的“谁”就是文件描述符,可以是socket句柄等)。其中比较重要的就是struct epoll_event结构体,它包括union epoll_data,uint32_t events,其中epoll_data可以是句柄fd也可以是void *fd,此种情况可以在触发了相关事件后执行提前绑定的相关函数,方便统一管理。events变量一般控制事件的属性,设定给定的fd到底监听什么操作,读?写?等。
epoll一般与socket联用,整个的流程大致如下:
首先利用efd=epoll_create()创建一个efd句柄,然后利用利用Socket的方法创建并绑定生成一个句柄listen_fd,将struct epoll_event结构填满,events和epoll_data(一般*ptr中有一个句柄变量fd,第一个事件令其等于listen_fd),再利用函数epoll_ctl,将epoll_event事件即下表达式中的event放入efd池中,并并绑定句柄listen_fd,如下
epoll_ctl (efd,EPOLL_CTL_ADD, listen_fd, &event);
最后我们只需要调用epoll_wait等待
epoll_wait (efd,events, MAXEVENTS, -1);
此表达式中efd为池句柄,events为struct epoll_event数组,存放触发的事件,MAXEVENTS是自定义的最大池中数量,-1表示永久等待(当然也可以写正整数表示等待时间)。等到消息来了触发某事件,我们处理events中的事件即可。第一次响应的事件一般是用于连接的句柄响应的时间,我们在那里accept一下然后将其返回的句柄再做成一个event放入efd池中,继续循环来反应。
epoll的ET模式和LT模式就是edgetrigger 和level trigger。边缘触发相当于数据来了触发一次,不管你是否读完都不再触发,一般利用while(1)读完数据,然后break出来;水平触发是数据来了,你没读完还能够继续触发该事件来读取,有一篇博客代码很直观,贴下网址:
https://blog.youkuaiyun.com/hnlyyk/article/details/50946194
里面可能有些小问题,如未加头文件,未加struct等,大家根据自己报错修改很容易。
附:
https://blog.youkuaiyun.com/jammg/article/details/51854436
https://blog.youkuaiyun.com/luyinquan/article/details/5407394