打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
select 错误,Invalid argument 或 Bad file descrip...

select 错误,Invalid argument 或 Bad file descriptor

日期:2009-11-19 | 分类:c & c++

之前有一个刷 squid 的 purge 程序,大约要刷20台机器,当时采用多线程 + 非阻塞(select)模式,发现一个很奇怪的问题,当线程数多于52时,select 经常返回出错,
22 Invalid argument
9  Bad file descriptor
不得其解。

最近温习unip,读到select时,终于明白了。select 最多可以检查FD_SETSIZE(通常是1024)个描述符。结合fd_set 的实现(FD_SET 在 描述符(大小)对应的位置1),明白了,select 可以检查的描述符最大为FD_SETSIZE,而不是最多FD_SETSIZE个描述符(虽然通常是这样,因为unix总是先用最小的)。

在 purge 程序中,20台机器,52个线程 52 × 20 = 1020,线程多于52,肯定就有描述符大于1024。虽然每个select 检查的描述符个数小于1024,但是整个进程的描述符个数已经大于1024(个数大于1024,那么描述符的大小肯定大于1024)。对于大于1024的描述符,FD_SET的处理方式是拿描述符对1024取模。假设描述符为1029,FD_SET(1029,&set)相当于FD_SET(5,&set),而 5 可能不是一个有效的描述符,当 select 去检查描述符 5 时,因为 5 不是有效的描述符,所以出 Invalid argument 或 Bad file descriptor 就比较合理了。

select 的正确语义应该时,整个进程中,select 最多可以检查1024个描述符,而不管用了多少 select 函数。更精确的描述是,select 只能检查描述符大小小于1024的描述符,当描述符个数大约1024,描述符大小就肯定大于1024。

可以epoll,或者poll解决这个问题,用libevent库(libevent,用选择平台上最好的I/O多路转接函数),更好。

收藏到:Del.icio.us
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
Linux中socket 错误编码表 errno
Select()系统调用及文件描述符集fd_set的应用
fcntl中文手册页,翻译的不好,请指正…翻译
fcntl函数的使用?控制文件描述符fd
[翻译] 第四章,高级串口编程
Linux select函数学习笔记
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服