epoll的使用总结

使用epoll来实现一个tcp server,中间碰到了不少使用细节上的问题,总结一下。

man epoll里推荐的使用方法

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使用总结的更多相关文章

  1. 从I/O复用谈epoll为什么高效

    上一篇文章中,谈了一些网络编程的基本概念.在现实使用中,用的最多的就是I/O复用了,无非就是select,poll,epoll 很多人提到网络就说epoll,认为epoll效率是最高的.单纯的这么认为 ...

  2. select、poll、epoll之间的区别总结

    select.poll.epoll之间的区别总结 05/05. 2014 select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪 ...

  3. (转载) Linux IO模式及 select、poll、epoll详解

    注:本文是对众多博客的学习和总结,可能存在理解错误.请带着怀疑的眼光,同时如果有错误希望能指出. 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案 ...

  4. linux下select/poll/epoll机制的比较

    select.poll.epoll简介 epoll跟select都能提供多路I/O复用的解决方案.在现在的Linux内核里有都能够支持,其中epoll是Linux所特有,而select则应该是POSI ...

  5. epoll LT/ET 深度剖析

    EPOLL事件的两种模型: Level Triggered (LT) 水平触发 .socket接收缓冲区不为空 有数据可读 读事件一直触发 .socket发送缓冲区不满 可以继续写入数据 写事件一直触 ...

  6. 非阻塞/异步(epoll) openssl

    前段时间在自己的异步网络框架handy中添加openssl的支持,当时在网络上搜索了半天也没有找到很好的例子,后来自己慢慢的摸索,耗费不少时间,终于搞定.因此把相关的资料整理一下,并给出简单的例子,让 ...

  7. select,epoll,poll比较

    介绍和比较 http://www.cnblogs.com/maociping/p/5132583.html 比较 http://www.dataguru.cn/thread-336032-1-1.ht ...

  8. Linux epoll

    一. epoll函数集 epoll主要有三个函数: 1. int epoll_create(int size); 创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大.这个参数不同于 ...

  9. linux下epoll实现机制

    linux下epoll实现机制 原作者:陶辉 链接:http://blog.csdn.net/russell_tao/article/details/7160071 先简单回顾下如何使用C库封装的se ...

  10. select、poll、epoll之间的区别总结[整理]

    select,poll,epoll都是IO多路复用的机制.I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作.但select ...

随机推荐

  1. jsonp实现数据跨域请求

    1.我们知道,哪怕跨域js文件中的代码(当然指符合web脚本安全策略的),web页面也是可以无条件执行的. 远程服务器remoteserver.com根目录下有个remote.js文件代码如下: al ...

  2. js取得数组重复元素

    function duplicates(arr) { var result=[]; arr.sort();//进行排序,重复的都相邻了 ;i<arr.length;i++){ ]&&am ...

  3. 你所不知道的html5与html中的那些事(四)——文本标签

    文章简介:       关于html5相信大家早已经耳熟能详,但是他真正的意义在具体的开发中会有什么作用呢?相对于html,他又有怎样的新的定义与新理念在里面呢?为什么一些专家认为html5完全完成后 ...

  4. opencvsharp BitmapSource图片截取问题

    private BitmapSource GetUiImage(FrameworkElement ui) { RenderTargetBitmap bmp=new RenderTargetBitmap ...

  5. 利用mysql客户端查询UCSC数据库

    UCSC Genome Browser是由University of California Santa Cruz (UCSC) 创立和维护的,该站点包含有人类.小鼠和大鼠等多个物种的基因组草图和注释信 ...

  6. 35.Docker安装Mysql挂载Host Volume

    连个文件系统有块区域Area,我们要做的是把两个Area做文件映射 jesse腾讯云上有个linux的环境,版本比较老了 简书的地址: https://www.jianshu.com/p/b3bf64 ...

  7. Json.net的常用语句JsonConvert.SerializeObject(对象)

    在ajax的已不请求中,常常返回json对象.可以利用json.net给我们提供的api达到快速开发. 例子: using System;using System.Collections;using ...

  8. 51nod1202【DP-树状数组维护】

    思路: DP[i]代表从1 到 i 以 a[i] 为末尾的子序列个数,dp[i]=dp[i]+dp[j](a[i]!=a[j]) +1 利用树状数组维护以值 a[i] 结尾的子序列个数. #inclu ...

  9. codeforces 547B【单调栈】

    题意: 有一个长度为n的序列,序列有长度为1...n的连续子序列, 一个连续子序列里面最小的值称作这个子序列的子序列的strength, 要求出每种长度的连续子序列的最大的strength. 思路: ...

  10. react学习之redux和redux-react用法

    前言 redux和react-redux的关系:   redux就是一个存储数据的对象,并提供了获取/设置store中的属性的解决方案,react-redux是连接react和redux桥梁的封装. ...