I/O多路复用的解决方法--select
Posted 别人都叫我陈科
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了I/O多路复用的解决方法--select相关的知识,希望对你有一定的参考价值。
ubuntu12.04
在实际情况中,人们往往遇到多个客户端连接服务器端的情况。由于如connet()、recv()和send() 、accept()等都是阻塞性函数,如果资源没有准备好,则调用该函数的进程将进入睡眠状态,这样就无法处理I/O多路复用的情况了。
使用fcntl()函数虽然可以实现非阻塞I/O或信号驱动I/O,但在实际使用时往往会对资源是否准备完毕进行循环测试,这样就大大增加了不必要的CPU资源的占用。在这里可以使用select()函数来解决这个问题,同时,使用select()函数还可以设置等待的时间,可以说功能更加强大。
所在库:
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
函数原型:
int select(int n, fd_set *read_fds, fd_set *write_fds, fd_set *except_fds, struct timeval *timeout);
n 最大文件描述符+1
read_fds 读文件描述符集合 (scanf recv)
write_fds 写文件描述符集合
except_fds 异常文件描述符
timeout 超时设置.
Null:一直阻塞,直到有文件描述符就绪或出错
时间值为0:仅仅检测文件描述符集的状态,然后立即返回
时间值不为0:在指定时间内阻塞,如果没有事件发生,则超时返回。
示例:
#include <sys/time.h>
struct timeval tv;
/* Wait up to five seconds. */
tv.tv_sec = 5;
tv.tv_usec = 0;
retval = select(1, &rfds, NULL, NULL, &tv);
返回值为>0 就是有事件发生,有几个文件描述符发生了变化
=0 超时返回
-1 出错
集合变量类型:fd_set r_fds;
集合变量运算宏:
FD_ZERO(&r_fds )
FD_SET(把某一个FD, 加入监控)
FD_ISSET(FD, fd_set),判断现在文件描述符对应的文件是不是有变化,如果有,返回值为真,无则假
FD_CLR
以上是关于I/O多路复用的解决方法--select的主要内容,如果未能解决你的问题,请参考以下文章