Linux网络:I/O多路转接select

一、select函数的功能

1.1select函数原型解析

select是系统提供的一个用来实现多路复用的输入/输出模型:

1、select系统调用可以用来让我们监视多个文件描述符的状态变化

2、程序会一直停在select这里进行等待,直到一个或多个被监视的文件描述符发生了状态改变。

select函数原型:

 #include <sys/select.h>

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

参数解析:

1、nfds 是需要监视的最大的文件描述符值+1。

2、rdset,wrset,exset 后三个参数分别对应需要检测的可读文件描述符集合、可写文件描述符集合、异常文件描述符集合。

3、参数 timeout 为 timeval的结构,用于设置 select()的等待时间。

timeval: 

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

1.2timeout的作用

1、NULL:表示 select()没有 timeout,也就是select 将一直被阻塞,直到某一个文件描述符发生了事件即发生了状态改变;

2、0:仅检测目标描述符集合的状态,然后立即进行返回,不等待外部事件的发生。

3、特定的时间值:如果在设定的指定时间断内没有事件发生,select将进行超时返回。

1.3fd_set

fd_set就是一个整数数组,严格来讲,其是一个位图结构。通过位图中不同的位对应的数来表示要监视的文件描述符,通常用于辅助配合selsect进行使用。

void FD_CLR(int fd, fd_set *set);  清除描述符集合set中相关的对应fd位

int FD_ISSET(int fd, fd_set *set);  测试描述符集合set中相关的对应fd位

void FD_SET(int fd, fd_set *set);  设置描述符集合set中相关的对应fd位

void FD_ZERO(fd_set *set);  清楚描述符集合set中全部的对应fd位

1.4select函数的返回值

1、执行成功返回文件描述词状态已经改变的个数。

2、返回 0 代表在描述词状态在timeout 时间之前没有改变,没有返回。

3、当有错误发生时则返回-1,错误码errno被设置,此时readfds,writefds, exceptfds 和 timeout四个参数的值变为不可预测。

select函数错误值: 

EBADF表示文件描述词为无效的或该文件已关闭。

EINTR表示此调用被信号所中断。

EINVAL表示参数n为负值。

ENOMEM表示核心内存不足。

 二、socket就绪

2.1读就绪

1、socket内核中, 接收缓冲区里的字节数,大于等于低水位标记 SO_RCVLOWAT。此时可以无阻塞的读该文件描述符中的数据, 并且返回值大于 0。

2、socket TCP 通信中, 如果对端关闭连接, 此时对该socket读,则返回值为0,表示另一方关闭。

3、监听的 socket 上有新的连接请求。

4、监听的 socket 上有未处理的错误。

2.2写就绪

1、socket内核中, 发送缓冲区里的字节数,大于等于低水位标记 SO_RCVLOWAT。此时可以无阻塞的向该文件描述符中写入数据, 并且返回值大于 0。

2、socket 的写操作被关闭(close /shutdown),如果对一个写操作被关闭的 socket 进行写操作, 会触发 SIGPIPE 信号;

3、socket 使用非阻塞 connect 连接成功或失败之后;

4、socket 上有未被读取的错误;

三、select的特点及不足

1、可监控的文件描述符个数取决于 sizeof(fd_set)的值,假设sizeof(fd_set)=512,每 bit 表示一个文件描述符,则该服务器上支持的最大文件描述 符是 512*8=4096。

2、将 fd 加入 select 监控集fd_set的同时,还需要再使用一个数据结构 array 也就是一个整形数组来保存放到 select 监控集中的fd。

3、当select返回后,之前创建的 array 作为源数据可以和 fd_set 进行 FD_ISSET 判断。

4、select 返回后会把以前加入的但并无事件发生的文件描述符 fd 清空,所以每次开始 select 前都要重新从 array 依次取得 fd 逐一加入,同时扫描array时取得fd最大值用于select的第一个参数。

 slect的不足:

每次调用 select, 都要手动去设置 fd 集合, 从接口使用角度来说非常不便。

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

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

select 支持的文件描述符数量太小。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C+超级飞侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值