Android C++ 系列:Linux Socket 编程(四)多路 IO 转接服务器
1. select
select 能监听的文件描述符个数受限于 FD_SETSIZE,一般为 1024,单纯改变进程打开 的文件描述符个数并不能改变 select 监听文件个数
解决 1024 以下客户端时使用 select 是很合适的,但如果链接客户端过多,select 采用 的是轮询模型,会大大降低服务器响应效率,不应在 select 上投入更多精力
nfds: 监控的文件描述符集里最大文件描述符加 1,因为此参数会告诉内核检测前多少个文件描述符的状态
readfds:监控有读数据到达文件描述符集合,传入传出参数
writefds:监控写数据到达文件描述符集合,传入传出参数
exceptfds:监控异常发生达文件描述符集合,如带外数据到达异常,传入传出参数
timeout:定时阻塞监控时间,3 种情况
NULL,永远等下去
设置 timeval,等待固定时间
设置 timeval 里时间均为 0,检查描述字后立即返回,轮询
2. poll
POLLIN 普通或带外优先数据可读,即 POLLRDNORM | POLLRDBAND
POLLRDNORM-数据可读
POLLRDBAND-优先级带数据可读
POLLPRI 高优先级可读数据
POLLOUT 普通或带外数据可写
POLLWRNORM-数据可写
POLLWRBAND-优先级带数据可写
POLLERR 发生错误
POLLHUP 发生挂起 POLLNVAL 描述字不是一个打开的文件
nfds 监控数组中有多少文件描述符需要被监控 timeout 毫秒级等待
-1:阻塞等,#define INFTIM -1 Linux 中没有定义此宏
0:立即返回,不阻塞进程
0:等待指定毫秒数,如当前系统时间精度不够毫秒,向上取值
如果不再监控某个文件描述符时,可以把 pollfd 中,fd 设置为-1,poll 不再监控此 pollfd,下次返回时,把 revents 设置为 0。
ppoll GNU 定义了 ppoll(非 POSIX 标准),可以支持设置信号屏蔽字,可参考 poll 模型自 行实现 C/S
3. epoll
epoll 是 Linux 下多路复用 IO 接口 select/poll 的增强版本,它能显著提高程序在大量并 发连接中只有少量活跃的情况下的系统 CPU 利用率,因为它会复用文件描述符集合来传递结 果而不用迫使开发者每次等待事件之前都必须重新准备要被侦听的文件描述符集合,另一点 原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核 IO 事件 异步唤醒而加入 Ready 队列的描述符集合就行了。
目前 epell 是 linux 大规模并发网络程序中的热门首选模型。
epoll 除了提供 select/poll 那种 IO 事件的电平触发(Level Triggered)外,还提 供了边沿触发(Edge Triggered),这就使得用户空间程序有可能缓存 IO 状态,减少 epoll_wait/epoll_pwait 的调用,提高应用程序效率。
一个进程打开大数目的 socket 描述符cat /proc/sys/fs/file-max
4. 总结
本文介绍了 Linux 多路复用的三种技术:select、poll、epoll。
版权声明: 本文为 InfoQ 作者【轻口味】的原创文章。
原文链接:【http://xie.infoq.cn/article/f87ea32a8e6e32887f7e80d50】。文章转载请联系作者。
评论