您好,欢迎来到爱问旅游网。
搜索
您的当前位置:首页文件I/O控制之select

文件I/O控制之select

来源:爱问旅游网

1.文件 I/O多路转接模型
 在文件I/O控制之fcntl文章介绍了文件I/O阻塞的模式. 通过fcntl函数设置文件I/O为阻塞后,read/write函数对该文件操作时,如果条件不满足时(如串口没数据,那就一直等到有数据),read/write操作一直阻塞当前进程直到read/write操作完成.而在多路转接模型下,如果请求的I/O操作阻塞(如read操作阻塞),它只会让某个函数阻塞(如read操作),其他操作(如write操作)还是可以进行的.
select机制可以实现文件 I/O多路转接模型,基本思路是: 对文件I/O操作可以设置多个(如read,write,open等),谁的条件满足了,就执行哪操作.

2.select 机制
机制中提供一fd_set的数据结构,实际上是一long类型的,每一个数组元素都能与一打开的(不管是socket句柄,还是其他文件或或设备句柄)建立联系,建立联系的工作由程序员完成,当调用select()时,由根据IO状态修改fd_set的内容,由此来通知执行了select()的进程哪一socket或文件发生了可读或可写事件

3. select function
select函数用于在非阻塞中,当一个套接字或一组套接字有信号时通知你,系统提供select函数来实现多路复用输入/输出模型,原型:int select(int maxfd,fd_set *rdset,fd_set *wrset,fd_set *exset,struct timeval *timeout);
所在的头文件为:#include <sys/time.h> 和#include <unistd.h>

4.1参数
(1)maxfd:是需要监视的最大的文件描述符值+1;
(2)rdset:对应于需要检测的可读文件描述符的集合
(3)wrset:可写文件描述符的集合
(4)exset:异常文件描述符的集合
(5)struct timeval: 结构用于描述一段时间长度,如果在这个时间内,需要监视的描述符没有事件发生则函数返回,返回值为0。
    1).timeout=NULL(阻塞:select将一直被阻塞,直到某个文件描述符上发生了事件)
    2).timeout所指向的结构设为非零时间(等待固定时间:如果在指定的时间段里有事件发生或者时间耗尽,函数均返回)
    3).timeout所指向的结构,时间设为0(非阻塞:仅检测描述符集合的状态,然后立即返回,并不等待外部事件的发生)
struct timeval{      

        long tv_sec;   /*秒 */
        long tv_usec;  /*微秒 */   

    }
 

readset, writset, exceptset,指向描述符集。这些参数指明了我们关心哪些描述符,和需要满足什么条件(可写,可读,异常)。一个文件描述集保存在 fd_set 类型中。fd_set类型变量每一位代表了一个描述符。我们也可以认为它只是一个由很多二进制位构成的数组。如下图所示:

 

5.文件描述符结构体  fd_set
#include<sys/select.h>

/* fd_set for select and pselect.  */
typedef struct
  {
#ifdef __USE_XOPEN
    __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->fds_bits)
#else
    __fd_mask __fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->__fds_bits)
#endif
  } fd_set;
 

6.文件描述符处理函数
对于fd_set类型通过下面四个宏来操作:
    FD_ZERO(fd_set *fdset) 将指定的文件描述符集清空,在对文件描述符集合进行设置前,必须对其进行初始化,如果不清空,由于在系统分配内存空间后,通常并不作清空处理,所以结果是不可知的。
    FD_SET(fd_set *fdset)中增加一个新的文件描述符。 用于在文件描述符集合
    FD_CLR(fd_set *fdset) 用于在文件描述符集合中删除一个文件描述符。
    FD_ISSET(int fd,fd_set *fdset) 用于测试指定的文件描述符是否在该集合中。

7.用法
 fd_set fdset;
 FD_ZERO(&fdset);
 FD_SET(sock, &fdset);
 struct timeval tv;
        tv.tv_sec  = s_serverResponseTimeout;
        tv.tv_usec = 0;
do{
        if(select(sock+1, &fdset, NULL, NULL, &tv) > 0)
        {
        ......
        }
     }while()

 

 

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- awee.cn 版权所有 湘ICP备2023022495号-5

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务