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个

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

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

突破Select 1024 限制

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

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

转自:http://m.blog.csdn.net/blog/wuzili1234/12450451 我原来自以为对select就算不熟,基本原理和使用方法也略知一二了,做了一年多的服务...

Linux select 文件描述符1024限制

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

Linux select 文件描述符1024限制------此处容易导致core dump

转载地址: http://blog.csdn.net/sxtobj/article/details/53170782 最近系统出现宕机的情况,分析core文件,所有的线程都在select处。 最...
  • stpeace
  • stpeace
  • 2017年06月25日 12:58
  • 291

Linux select学习笔记(附:监测多个文件描述符状态的例子)

select(I/O多工机制) 表头文件 #include #include #include 定义函数 int select(int n,fd_set...
  • wm111
  • wm111
  • 2014年12月25日 15:09
  • 1300

Linux - Select()系统调用及文件描述符集fd_set的应用

select()机制中提供一fd_set的数据结构,实际上是一long类型的数组,每一个数组元素都能与一打开的文件句柄(不管是socket句柄,还是其他文件或命名管道或设备句柄)建立联系,建立联系的工...

select函数——单进程监视多个文件描述符

程序期待着来自两个源端的输入,但不知道哪个源端的输入先到。如果程序试图从源端A读入,而实际上只有来自源端B的输入可用,那么程序就会发生阻塞,怎么办? 保持阻塞状态,直到一组条件中至少有一个条件为真为...
  • zhccl
  • zhccl
  • 2012年07月15日 23:51
  • 3784

select监听多个客户端 -- linux函数

使用select函数可以以非阻塞的方式和多个socket通信。程序只是演示select函数的使用,功能非常简单,即使某个连接关闭以后也不会修改当前连接数,连接数达到最大值后会终止程序。 1. 程序使...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:linux下的select简直太奇葩了:1024限定的不只是监听的个数,还是文件描述符的最大值,注意,是值
举报原因:
原因补充:

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