I/O多路复用(一):select

2017-07-08 14:38 阅读 599 次 评论 0 条

Linux提供了三种I/O多路复用方案:select、poll和epoll。select系统调用是用来让我们的程序监视多个文件描述状态变化的,它是最早的以实现同步I/O多路复用的机制。

select函数解析

系统提供select函数来实现多路复用输入/输出模型,当调用select()后,程序会停在select这里等待,直到被监视的文件句柄至少有一个发生了状态改变。

文件句柄,本质上就是文件描述符,是一个整数,比如我们最熟悉的0(stdin)、1(stdout)、3(stderr)。

select()函数的参数含义如下:

readfds、writefds、exceptfds三个参数均是输入、输出型参数,输入表示关心指定文件描述符对应的特定事件发生。输出表示指定文件描述符对应的事件就绪,就绪后内核将会去修改这些文件描述符的集合。

fd_set底层使用位图实现,每一位对应一个文件描述符,作为输入时,为1代表select需要监听这个文件描述符;作为输出时,为1则代表等待的事件就绪。

struct timeval结构用于描述一段时间长度,如果在这个时间内,需要监视的描述符没有事件发生则函数返回0。

timeout这个参数有三种可能:

下面的宏提供了处理这三种描述词组的方式:

返回值和错误码:select()调用成功时,返回三个集合中I/O就绪的文件描述符总数;返回0代表在描述符词状态改变前已超过timeout,没有返回;出错返回-1,并把error的值设定为以下值:

select模型的特点

① 可监控的文件描述符个数取决于sizeof(fd_set)的值,调整上限受编译内核时的变量值。

② 将fd加入select监控集的同时,还要在使用一个数据结构array保存放到select监控集中的fd,原因有二:

③ select模型必须在select前循环array(加fd,取maxfd),select返回后循环array(FD_ISSET)判断是否有事件发生。

select的优缺点

☞ 缺点(相对于poll与epoll而言)

⑴ 对socket进行扫描时是线性扫描,即采用轮询的方法,效率较低。

⑵ 每次调用select,都需要将fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大。

⑶ 单个进程可监视的fd数量被限制,即能监听的端口大小有效。

⑷ 每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时会很大。

☞ 优点(相对于poll、多进程与多线程而言)

① select的可移植性更好,在某些Unix上并不支持poll。

② select对于超时值提供了更好的精度:微秒,而poll是毫秒。

③ 相对于多进程与多线程服务器,select免去了系统调度的开销。

select网络服务器

select网络服务器的功能:可以让多个客户端连接,并将客户端发送的信息回显在服务器上,类似于QQ群的子功能。

版权声明:本文著作权归原作者所有,欢迎分享本文,谢谢支持!
转载请注明:I/O多路复用(一):select | 术与道的分享
1024do.com导航_术与道导航平台

发表评论


表情