java中的接口是类吗
245
2022-10-30
I/O多路转接之select
I/O多路转接之select(只负责等)
系统提供select函数来实现多路复用输入/输出模型。
传向select的参数告诉内核:
1)我们所关心的文件描述符。
参数nfds是需要监视的最大的文件描述符值+1;
2)对每个描述符,我们所关心的状态。
rdset,wrset,exset分别对应于需要检测的可读文件描述符的集合,可写文件描述符的集合及异常文件描述符的集合。
监视的文件描述符分为三类set,每一种对应等待不同的事件。readfds中列出的文件描述符被监视是否有数据可供读取(如果读取操作完成则不会 阻 塞)。writefds中列出的文件描述符则被监视是否写入操作完成而不阻塞后,exceptfds中列出的文件描述符则被监视是否发生异常,或者无 法控制的数据是否可用(这些状态仅仅应用于套接字)。这三类set可以是NULL,这种情况下select()不监视这一类事件。
下面的宏提供了处理这三种描述词组的方式:
FD_ZERO移除指定set中的所有文件描述符。每一次调用select()之前都应该先调用它;
FD_CLR则从指定的set中移除一个文件描述符;
FD_SET添加一个文件描述符到指定的set中;
FD_ISSET测试一个文件描述符是否指定set的一部分。如果文件描述符在set中则返回一个非0整数,不在则返0,FD_ISSET在调用select() 返回之后使用,测试指定的文件描述符是否准备好相关动作。
3)我们要等待多长时间。(我们可以等待无限长的时间,等待固定的一段时间,或者根本就不等待)
timeout参数是一个指向timeval结构体的指针,timeval定义如下:
struct timeval结构用于描述一段时间长度,如果在这个时间内,需要监视的描述符没有事件发生则函数返回,返回值为0。
从 select函数返回后,内核告诉我们以下信息:
1)已经做好准备的描述符的个数。
2)对于三种条件哪些描述符已经做好准备。(读,写,异常)
执成功则返回件描述词状态已改变的个数;如果返回0代表在描述词状态改变前已超过timeout时间,没有返回;当有错误发时则返回-1,错误原因存于errno,此时参数readfds,writefds,exceptfds和timeout的值变成不可预测。错误值可能为:EBADF 件描述词为效的或该件已关闭 ,EINTR 此调被信号所中断 EINVAL 参数n 为负值,ENOMEM 核内存不。
#include
select优点:
(1)相较于之前多线程的方法,使用select不用创建线程,更方便
(2)select目前几乎在所有的平台上都支持,其良好跨平台支持也是它的一个优点
select缺点:
(1)每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大
(2)同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大
(3)能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,因为它依赖于文件系统
(4)select()所维护的文件描述符的数据结构,随着文件描述符数量的增大,其复制的开销也线性增长。
(5)由于网络响应时间的延迟使得大量TCP连接处于非活跃状态,但调用select()会对所有socket进行一次线性扫描,这也会有一些开销
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~