linux下的select简直太奇葩了:1024限定的不只是监听的个数,还是文件描述符的最大值,注意,是值

转载 2015年07月10日 17:45:35

转自:http://m.blog.csdn.net/blog/wuzili1234/12450451

我原来自以为对select就算不熟,基本原理和使用方法也略知一二了,做了一年多的服务器编程,好歹知道linux下的select不支持超过1024个的描述符,好歹知道可以通过内核编译来重设FD_SETSIZE,也敢大言不惭地说select函数的maxfd应该是监测的所有fd值中取最大的+1,甚至连世界上有select * from的语法都知道,结果,今天直接扎扎实实栽在了select上面了:我生生花了近2个小时来跟踪select的奇葩点。很让人痛苦的2个小时啊,那么多关联点,盘根错节揉在一块,每条支脉都显得那么无辜,实在有种拔剑四顾心茫然的感觉。不过,说起来也要感谢select,要不是它,这么让人痛苦的2个小时不知道怎么度过呢!总之,当我通过再三排除最终跟扯大肠一样扯出select的各种纠结时,脑海里不由得浮现出了一句箴言:“一切有为法,如梦幻泡影,如露亦如电,应作如是观”。善哉。


  先说一下问题的表象,来源是这样的:我用客户端一次性发起超过2000个连接,等连接全部就绪后,设为非阻塞,将他们FD_SET进readset和writeset,以接收和发送消息。当然,这里我还是有点上面提到的常识的,不是一下子全部FD_SET进去,而是分批次,这里我是设成900,每次FD_ZERO之后我都设一个计数,FD_SET超过900个的socket就停止。因为每个连接做的事情很少,先发一次数据,再收一次数据就可以直接关闭,而在关闭之后就不再FD_SET相应的socket,所以理论上是可以依次处理完的。但这也是理论上,问题来了,我发现当第一批的连接(即前900个)关闭之后,后面的连接在读数据时纷纷提示:resource temporarily unavailable。一开始我以为我没处理好LT水平触发,结果搞了半天没效果,又怀疑到服务器端写数据时的处理,因为是边缘触发的,所以ET模式的EAGAIN、EWOULDBLOCK、EINTR写法重新查了好久,还是没有头绪。然后开始怀疑最大文件打开数,只是心里仍然觉得奇怪,因为能连续connect有2000次就已经说明不是打开数量限制的问题了,但我仍然ulimit -n xxxx,修改什么fs.file-max,设置Hn、sn的,syctl搞了一堆。还是搞不定。


  万般无奈之下,突然鬼使神差般,把900改成1,就是说每次只让它监听一个socket上的事件,等前一个socket上的事件处理完再继续监听下一个socket。然后,奇葩点出现了,我打印出的输出信息显示当fd=1024这个socket处理完,开始监听值为1025的socket时,select立刻返回,并不理会我所设定的1秒的timeout超时设定。真的是1024限定的问题啊,我的第一反应是:应该是我没设好文件打开个数,然后我傻愣愣地重启了虚拟机。还是不行!这时我才开始怀疑select的第一个参数maxfd所代表的含义:没错啊,取所有监听的fd的最大值然后+1,网上很多教程都是这么写的啊。又开始查看FD_SET、FD_ISSE和FD_CLR的源码,没看出什么蹊跷。网上搜select的1024限制又有一堆人说应该重新编译linux内核,可是我只监听一个啊,只不过这个socket的值是1025而已。还有人专门写教程澄清说FD_SET几个值大于1024的描述符进去是可以的,可是我的就出错啊。


  不过幸好我又搜到了这个http://bbs.chinaunix.net/thread-1791112-1-1.html,才解决了我的疑问。


  最后,我决定放弃在linux下使用select。


深入解析为何select最多只能监听1024个

深入解析为何select最多只能监听1024个
  • xuefeng0707
  • xuefeng0707
  • 2014年04月10日 22:54
  • 3435

为何select做多只支持1024个描述符

内核代码中,原因一览无余 每一位一个描述符,总共1024/8/4*32=1024个
  • wejoncy
  • wejoncy
  • 2016年05月06日 20:14
  • 1748

Linux select 文件描述符1024限制

最近系统出现宕机的情况,分析core文件,所有的线程都在select处。 最后怀疑是文件描述符超过了1024。但是想到Apache也是采用select的io模型。所以还是很不理解。 查看了Linu...
  • sxtobj
  • sxtobj
  • 2016年11月15日 14:25
  • 1053

突破Select 1024 限制

前言: 在很多比较各种网络模型的文章中,但凡提到select模型时,都会说select受限于轮询的套接字数量,这个数量也就是系统头文件中定义的FD_SETSIZE值(例如64)。但事实上这个算不上真的...
  • zhji09
  • zhji09
  • 2009年03月23日 09:16
  • 2195

select的fd超过1024将会非常危险------FD_SET导致core dump

关于linux select无须多说, 来看代码: #include #include #include #include #include #include int main(int argc,...
  • stpeace
  • stpeace
  • 2017年06月25日 15:20
  • 2611

[C++] 关于FD_SETSIZE大小的问题

关于FD_SET的注意事项
  • gogdizzy
  • gogdizzy
  • 2011年05月17日 20:38
  • 8149

select模型

在Windows中所有的socket函数都是阻塞类型的,也就是说只有网络中有特定的事件发生时才会返回,在没有发生事件时会一直等待,虽说我们将它们设置为非阻塞状态,但是在对于服务器段而言,肯定会一直等待...
  • lanuage
  • lanuage
  • 2015年09月15日 22:12
  • 930

linux 如何设置进程所能打开的最大文件描述符个数

linux下文件描述符的介绍  (2012-10-02 16:01:56) 转载▼ 标签:  描述符   调用   返回   进程   ...
  • boshuzhang
  • boshuzhang
  • 2016年04月15日 10:28
  • 2621

为什么linux select函数的第一个参数总应该是fdmax + 1 ?

先说明一下, 在Windows中, 并不要求select函数的第一个参数总应该是fdmax + 1, 那linux中为什么又是呢?          这就涉及到linux select第一个参数的函数...
  • stpeace
  • stpeace
  • 2017年06月23日 08:28
  • 2748

select+inotify监控linux文件变化遇到的坑

使用select+inotify监控目录里面文件的创建与删除,发现bug.bug描述如下红色部分: void listenDev(void * ptr) { inotifyFd=-1; inot...
  • cf125313
  • cf125313
  • 2017年10月20日 10:50
  • 210
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux下的select简直太奇葩了:1024限定的不只是监听的个数,还是文件描述符的最大值,注意,是值
举报原因:
原因补充:

(最多只允许输入30个字)