epoll使用总结
epoll的使用总结
使用epoll来实现一个tcp server,中间碰到了不少使用细节上的问题,总结一下。
man epoll里推荐的使用方法
#define MAX_EVENTS 10
struct epoll_event ev, events[MAX_EVENTS];
int listen_sock, conn_sock, nfds, epollfd; /* Set up listening socket, 'listen_sock' (socket(),
bind(), listen()) */ epollfd = epoll_create();
if (epollfd == -) {
perror("epoll_create");
exit(EXIT_FAILURE);
} ev.events = EPOLLIN; // 不要写成ev.events = EPOLLIN | EPOLLET;
ev.data.fd = listen_sock;
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, listen_sock, &ev) == -) {
perror("epoll_ctl: listen_sock");
exit(EXIT_FAILURE);
} for (;;) {
nfds = epoll_wait(epollfd, events, MAX_EVENTS, -);
if (nfds == -) {
perror("epoll_pwait");
exit(EXIT_FAILURE);
} for (n = ; n < nfds; ++n) {
if (events[n].data.fd == listen_sock) {
conn_sock = accept(listen_sock,
(struct sockaddr *) &local, &addrlen);
if (conn_sock == -) {
perror("accept");
exit(EXIT_FAILURE);
}
setnonblocking(conn_sock);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd = conn_sock;
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock,
&ev) == -) {
perror("epoll_ctl: conn_sock");
exit(EXIT_FAILURE);
}
} else {
do_use_fd(events[n].data.fd);
}
}
}
要点:
1.listen_sock使用LT模式,其他使用ET模式,这样就不会遗漏后续的connect请求
(其实还有另外一种方式,listen_sock也使用ET模式,只是要用while包裹accept语句,直到返回-1,这里我们不讨论)
在遗落后续的connect请求这个问题上花费了很多时间。
具体测试表现是:1000个client发起tcp connect,并在连接成功之后发送数据。测试中,1000个client正常连接并发送数据,但epoll中未收到部分client的连接请求。
使用netstat命令查看有以下发现:
netstat -apn|grep |wc -l netstat -apn|grep |grep -|wc -l
系统已经建立了1000个tcp连接,但是其中有小部分连接不是由我们的程序负责建立的。
netstat -apn|grep |grep -
使用上面的命令能够发现,有小部分连接处于ESTABLISHED状态,但进程信息那一栏却是"-"
这应该是ET模式下连接就绪触发了一次,但我们的程序没有来及处理,ET不会再触发,导致这小部分连接再没有机会得到accept处理。
解决这个问题的话,把listen_sock(负责listen和accept新连接的socket)设成LT模式,这样没来得及处理的connect请求会在下次执行到epoll_wait时继续得到处理。
2.epoll_wait的参数设置
#include <sys/epoll.h>
int epoll_wait(int epfd, struct epoll_event *events,
int maxevents, int timeout);
maxevents参数越小,相同请求数的情况下,需要调用更多次数的epoll_wait来处理这些在epoll队列里的请求,可能会有效率损失。
timeout参数:一般设置成-1,即没有请求时无限等待。
参考资料:
1.http://stackoverflow.com/questions/6401642/dealing-with-listening-socket-by-epoll
2.http://stackoverflow.com/questions/9577230/epoll-create-and-epoll-wait
3.http://stackoverflow.com/questions/16640430/maxevents-parameter-in-epoll-wait-and-the-events-array-size
epoll使用总结的更多相关文章
- 从I/O复用谈epoll为什么高效
上一篇文章中,谈了一些网络编程的基本概念.在现实使用中,用的最多的就是I/O复用了,无非就是select,poll,epoll 很多人提到网络就说epoll,认为epoll效率是最高的.单纯的这么认为 ...
- select、poll、epoll之间的区别总结
select.poll.epoll之间的区别总结 05/05. 2014 select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪 ...
- (转载) Linux IO模式及 select、poll、epoll详解
注:本文是对众多博客的学习和总结,可能存在理解错误.请带着怀疑的眼光,同时如果有错误希望能指出. 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案 ...
- linux下select/poll/epoll机制的比较
select.poll.epoll简介 epoll跟select都能提供多路I/O复用的解决方案.在现在的Linux内核里有都能够支持,其中epoll是Linux所特有,而select则应该是POSI ...
- epoll LT/ET 深度剖析
EPOLL事件的两种模型: Level Triggered (LT) 水平触发 .socket接收缓冲区不为空 有数据可读 读事件一直触发 .socket发送缓冲区不满 可以继续写入数据 写事件一直触 ...
- 非阻塞/异步(epoll) openssl
前段时间在自己的异步网络框架handy中添加openssl的支持,当时在网络上搜索了半天也没有找到很好的例子,后来自己慢慢的摸索,耗费不少时间,终于搞定.因此把相关的资料整理一下,并给出简单的例子,让 ...
- select,epoll,poll比较
介绍和比较 http://www.cnblogs.com/maociping/p/5132583.html 比较 http://www.dataguru.cn/thread-336032-1-1.ht ...
- Linux epoll
一. epoll函数集 epoll主要有三个函数: 1. int epoll_create(int size); 创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大.这个参数不同于 ...
- linux下epoll实现机制
linux下epoll实现机制 原作者:陶辉 链接:http://blog.csdn.net/russell_tao/article/details/7160071 先简单回顾下如何使用C库封装的se ...
- select、poll、epoll之间的区别总结[整理]
select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作.但select ...
随机推荐
- MODBUS ASCII和RTU两种模式的区别、优缺点
转自:http://blog.sina.com.cn/s/blog_89f286ad0102uzju.html 下表是MODBUS ASCII协议和RTU协议的比较: 协议 开始标记 结束标记 校验 ...
- Pointer 指针
利用指针访问对象,指针指向一个对象,允许使用解引用符(操作符*)来访问对象 int ival = 42; int *p = &ival;//p存放变量ival的内存地址,p是指向变量ival的 ...
- html中连续点击某个标签会出现蓝色的解决方法
给标签加上下面的属性就可以了,也可以把这些属性建立一个class名,谁需要的时候加上也ok -moz-user-select: none; /*mozilar*/ -webkit-user-selec ...
- Linux 之添加系统环境变量
PATH 值是一系列目录,当执行命令时,linux就在这些目录下查找,其格式为: PATH=$PATH:<PATH1>:<PATH2>:<PATH3>:------ ...
- 如何阻止冒泡&&浏览器默认行为
摘要 很多同学对阻止事件冒泡和阻止事件默认行为容易混淆,项目中因为一些原因也需要阻止浏览器的一些默认行为,这里就简单总结一下. 阻止事件冒泡 什么是事件冒泡这里就不再赘述了,网上的文章一大把,这里就简 ...
- ZOJ3526【缩点思想】
一开始做的时候(TLE),A,C,G这三类作为边,然后点和点直接建边搜个环:then time BOOM! 可以发现只属于"A"类的之间都并在一起就好,同理"G" ...
- docker中容器和镜像的区别
自学docker过程中一直搞不明白 镜像容器的关系,网上查阅看到一篇文章觉得讲的很好,转载记录. 转自 http://blog.csdn.net/chszs/article/details/48252 ...
- js中的原型以及原型链
在js中原型是每个构造函数的属性: 这个算 js 核心概念的一部分 var f1 = new Foo(); 对象 f1 的构造函数就是 Foo , f1的原型 __proto__ 就指向构造函数 Fo ...
- JVM 内存分析
简述JVM垃圾回收机制 垃圾回收机制时Java提供的自动释放内存空间的机制. 垃圾回收机制时JVM自导的一个线程,用于回收没有被引用的对象. JVM有一个运行时的数据区来管理内存.其主要包括五大部分: ...
- 导出war包
1. 使用Eclipse 导出 右键web工程 -> export -> war file 将导出的war文件放到tomcat安装目录的webapps下,然后启动tomcat,就会发现在该 ...