既然说是用select踩到的坑,那么就先直接贴一段使用select的代码上来瞅一下:

    bool SocketAction(int fd, const char* buf, size_t len, uint64_t milli_expire) {
struct timeval tv;
tv.tv_sec = milli_expire / 1000;
tv.tv_usec = (milli_expire % 1000) * 1000;
fd_set rd_set, wt_set;
FD_ZERO(&rd_set);
FD_ZERO(&wt_set);
FD_SET(fd, &rd_set);
FD_SET(fd, &wt_set); int ret = 0;
while (true) {
ret = select(fd+1, &rd_set, &wt_set, nullptr, &tv);
if (ret < 0 && errno == EINTR) continue;
break;
} if(FD_ISSET(fd, &rd_set)) {
char rd_buf[1024] = {0};
ret = read(fd, rd_buf, sizeof(rd_buf));
if(ret < 0) return false;
printf("%s\n", rd_buf);
} else if(FD_ISSET(fd, &wt_set)) {
ret = send(fd, buf, len, 0);
if(ret < 0) return false;
} return true;
}

上面的代码着实非常easy,仅仅是针对某一个socket fd进行读写操作,从逻辑上来说应该是没有不论什么问题的。然而这个在实际的使用过程中确实会出现故障。我们程序中封装了socket的操作,如上代码的方式使用了select。

在出现大量的socket连接时,会出现宕机现象,而且宕机生成的core文件的堆栈也莫名其妙的被破坏了。

遇到这个情况时。我直接被震惊了,由于细致检查了代码确实没有发现不论什么问题。为什么每次都是连接数达到快1500的时候就出现宕机呢?

刚開始以为是其它的逻辑出了问题。于是细致检查了其它的逻辑确实也没有发现存在不论什么问题,而且从堆栈被破坏的情况上分析,也怀疑是某个使用中出现了数组越界訪问引发的。但在整个逻辑中使用的都是stl里的容器,没有申请数组,出现读写越界着实无法理解。

此后仅仅能怀疑底层封装的问题。在一步步尝试凝视代码的过程中。发现select使用的地方出现了问题。那么问题到底在哪里呢?

 int select(int nfds, fd_set *readfds, fd_set *writefds,

                  fd_set *exceptfds, struct timeval *timeout);

 nfds is the highest-numbered file descriptor in any of the three sets, plus 1.

在select的使用manual中,select的定义和nfds的说明如上所看到的。也仅仅是说明了select的nfds是最大的文件描写叙述符+1。在实际的使用过程中也确实有这么使用。好像也确实没有问题。然而,不止这么简单。select的文件描写叙述符的最大值实际是有一个潜在规则的。那就是select的最大文件描写叙述符最大是1024。该值在centor os系统中。定义在文件/usr/include/sys/select.h文件里。例如以下:

   78 /* Maximum number of file descriptors in `fd_set'.  */

   79 #define FD_SETSIZE      __FD_SETSIZE

而__FD_SETSIZE则定义在:/usr/include/bits/typesizes.h 中,例如以下:

   62 /* Number of descriptors that can fit in an `fd_set'.  */

   63 #define __FD_SETSIZE        1024

这下能够理解了吧。在socket大于1024时。文件描写叙述符自然就大于1024,则在使用select时訪问的大小就实际超越了系统中对于select的支持。因此出现读写越界,造成程序的宕机。

这次所踩的坑很隐晦,但也说明了一个问题。在使用系统接口时须要谨慎。尽管可能用法并没有错误,但也要在使用的时候多注意其“潜规则”。

我用select做多路复用踩到的坑的更多相关文章

  1. gevent协程、select IO多路复用、socketserver模块 改造多用户FTP程序例子

    原多线程版FTP程序:http://www.cnblogs.com/linzetong/p/8290378.html 只需要在原来的代码基础上稍作修改: 一.gevent协程版本 1. 导入geven ...

  2. 用select (多路复用)模拟一个 socket server

    需求:用select (多路复用)模拟一个 socket server.可以接收多并发. 1. 一开始是检测自己,如果我有活动了,就说明有客户端要连我了. #用select去模拟socket,实现单线 ...

  3. wrk 使用记录及踩过的坑

    wrk是什么?https://github.com/wg/wrk wrk 是一个非常小巧高效的开源性能测试工具,支持lua脚本来创建复杂的测试场景.wrk 的一个很好的特性就是能用很少的线程压出很大的 ...

  4. 【转载】Fragment 全解析(1):那些年踩过的坑

    http://www.jianshu.com/p/d9143a92ad94 Fragment系列文章:1.Fragment全解析系列(一):那些年踩过的坑2.Fragment全解析系列(二):正确的使 ...

  5. 使用ffmpeg视频编码过程中踩的一个坑

           今天说说使用ffmpeg在写视频编码程序中踩的一个坑,这个坑让我花了好多时间,回头想想,非常多时候一旦思维定势真的挺难突破的.以下是不对的编码结果:                   ...

  6. 《C++之那些年踩过的坑(二)》

    C++之那些年踩过的坑(二) 作者:刘俊延(Alinshans) 本系列文章针对我在写C++代码的过程中,尤其是做自己的项目时,踩过的各种坑.以此作为给自己的警惕. 今天讲一个小点,虽然小,但如果没有 ...

  7. 《C++之那些年踩过的坑(三)》

    C++之那些年踩过的坑(三) 作者:刘俊延(Alinshans) 本系列文章针对我在写C++代码的过程中,尤其是做自己的项目时,踩过的各种坑.以此作为给自己的警惕. [版权声明]转载请注明原文来自:h ...

  8. 《C++之那些年踩过的坑(附录一)》

    C++之那些年踩过的坑(附录一) 作者:刘俊延(Alinshans) 本系列文章针对我在写C++代码的过程中,尤其是做自己的项目时,踩过的各种坑.以此作为给自己的警惕. [版权声明]转载请注明原文来自 ...

  9. CentOS7.2上用KVM安装虚拟机window10踩过的坑

    最近两个星期一直在琢磨kvm安装window10操作系统,并且通过桥接模式与外界通信,经历了九九八十一难,终于搞定.下面就记录以下我们在探索的过程中踩过的坑. 安装KVM 1. 系统要求:需要一台可以 ...

随机推荐

  1. 【转】unity自带寻路Navmesh入门教程(三)

    http://liweizhaolili.blog.163.com/blog/static/16230744201271225812998/ 继续介绍NavMesh寻路的功能,接下来阿赵打算讲一下以下 ...

  2. linux系统带宽监测脚本

    服务器可能经常遇到服务器出带宽跑满,不知如何查询被哪个进程占用的情况,有一款开源的英文软件iftop功能比较强大可以查询相关信息,可能刚接触linux系统的朋友不太会使用,在此写了一个功能比较简单无需 ...

  3. mysql查看语句执行状态的常见函数

    row_count() 返回上一个insert.update.delete语句的影响行数 found_rows() 返回上一个select查到的记录条数 last_insert_id() 返回上一次插 ...

  4. cf 853 D Michael and Charging Stations [dp]

    题面: 传送门 思路: 看到题目,第一思路是贪心,但是我很快就否决掉了(其实分类贪心也可以做) 然后就想,贪心不能解决的状态缺失,是否可以用dp来解决呢? 事实证明是可以的 我们设dp[i][j]表示 ...

  5. 【线性基】51nod1312 最大异或和&LOJ114 k大异或和

    1312 最大异或和 题目来源: TopCoder 基准时间限制:1 秒 空间限制:131072 KB 分值: 320 难度:7级算法题   有一个正整数数组S,S中有N个元素,这些元素分别是S[0] ...

  6. 浅谈C++三层架构

    浅谈C++三层架构 三层架构并不是MVC,MVC是一个很早就有的经典的程序设计模式,M-V-C分为三层,M(Model)-V(View)-C(Control). web开发中的三层架构是指:数据访问层 ...

  7. hosts修改备份

    # Modified hosts start # Armorgames Start 93.184.220.39 cache.armorgames.com 93.184.220.39 gamemedia ...

  8. CodeChef Counting on a directed graph

    Counting on a directed graph Problem Code: GRAPHCNT All submissions for this problem are available. ...

  9. HttpClient 简介与使用

    Http协议的重要性相信不用我多说了,HttpClient相比传统JDK自带的 URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端发送Http请求变得容易,而 ...

  10. jmeter登录测试

    测试步骤: 1.测试计划--右键添加--Threads--线程组 2. 线程组--右键--http信息头管理器 输入Content-Type=application/json,表示接口请求的默认设置: ...