IO多路转接 select

使用select这种IO多路转接方式需要调用一个同名函数select,这个函数是跨平台的,Linux、Mac、Windows都是支持的。程序猿通过调用这个函数可以委托内核帮助我们检测若干个文件描述符的状态,其实就是检测这些文件描述符对应的读写缓冲区的状态:

读缓冲区:检测里边有没有数据,如果有数据该缓冲区对应的文件描述符就绪

写缓冲区:检测写缓冲区是否可以写(有没有容量),如果有容量可以写,缓冲区对应的文件描述符就绪

读写异常:检测读写缓冲区是否有异常,如果有该缓冲区对应的文件描述符就绪

委托检测的文件描述符被遍历检测完毕之后,已就绪的这些满足条件的文件描述符会通过select()的参数分3个集合传出,程序猿得到这几个集合之后就可以分情况依次处理了。

select

函数原型

#include <sys/select.h>
struct timeval {
    time_t      tv_sec;         /* seconds */
    suseconds_t tv_usec;        /* microseconds */
};

int select(int nfds, fd_set *readfds, fd_set *writefds,
           fd_set *exceptfds, struct timeval * timeout);

函数参数:

  • nfds:委托内核检测的这三个集合中最大的文件描述符 + 1

    • 内核需要线性遍历这些集合中的文件描述符,这个值是循环结束的条件

    • 在Window中这个参数是无效的,指定为-1即可

  • readfds:文件描述符的集合, 内核只检测这个集合中文件描述符对应的读缓冲区

    • 传入传出参数,读集合一般情况下都是需要检测的,这样才知道通过哪个文件描述符接收数据
  • writefds:文件描述符的集合, 内核只检测这个集合中文件描述符对应的写缓冲区

    • 传入传出参数,如果不需要使用这个参数可以指定为NULL
  • exceptfds:文件描述符的集合, 内核检测集合中文件描述符是否有异常状态

    • 传入传出参数,如果不需要使用这个参数可以指定为NULL
  • timeout:超时时长,用来强制解除select()函数的阻塞的

    • NULL:函数检测不到就绪的文件描述符会一直阻塞。

    • 等待固定时长(秒):函数检测不到就绪的文件描述符,在指定时长之后强制解除阻塞,函数返回0

    • 不等待:函数不会阻塞,直接将该参数对应的结构体初始化为0即可。

函数返回值:

  • 大于0:成功,返回集合中已就绪的文件描述符的总个数

  • 等于-1:函数调用失败

  • 等于0:超时,没有检测到就绪的文件描述符

fd_set类型的参数

// 将文件描述符fd从set集合中删除 == 将fd对应的标志位设置为0        
void FD_CLR(int fd, fd_set *set);
// 判断文件描述符fd是否在set集合中 == 读一下fd对应的标志位到底是0还是1
int  FD_ISSET(int fd, fd_set *set);
// 将文件描述符fd添加到set集合中 == 将fd对应的标志位设置为1
void FD_SET(int fd, fd_set *set);
// 将set集合中, 所有文件文件描述符对应的标志位设置为0, 集合中没有添加任何文件描述符
void FD_ZERO(fd_set *set);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值