IO多路复用:select模型

select模型

  • select系统调用是用来让我们的程序监视多个文件描述符的状态变化的;
  • 程序会停在select这里,select循环不断地对所监控的描述符进行就绪判断,如果没有描述符就绪,就继续循环等待。
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);

nfds:指定待测试的描述符个数
readfds,writefds,exceptfds:指定了我们让内核测试读、写和异常条件的描述字
timeout

  • NULL:则表示select()没有timeout,select将一直被阻塞,直到某个文件描述符上发生了事件;
  • 0:仅检测描述符集合的状态,然后立即返回,并不等待外部事件的发生。
  • 特定的时间值:如果在指定的时间段里没有事件发生,select将超时返回。
    返回值:失败-1 超时0 成功>0

select原理:对fd_set的理解

fd_set:为一个存放文件描述符的信息的结构体,可以通过下面的宏进行设置

void FD_ZERO(fd_set *fdset);
//清空集合
void FD_SET(int fd, fd_set *fdset);
//将一个给定的文件描述符加入集合之中
void FD_CLR(int fd, fd_set *fdset);
//将一个给定的文件描述符从集合中删除
int FD_ISSET(int fd, fd_set *fdset);
// 检查集合中指定的文件描述符是否可以读写

建立监控集合,对描述符指定的事件(可读、可写、异常),当监控集合中的某个描述就绪了,则返回,并且告诉我们有几个描述符就绪,将监控描述符中没有就绪的描述符从集合中移除。
在这里插入图片描述
select对描述符进行监控,分了三种监控,分别是可读、可写、异常事件,如果想要对描述符进行监控,则将这个描述符添加到对应集合中。这个集合实际上一个位图,位图的默认大小是1024(不同的主机fd_set的默认大小不确定,总之,fd_set的大小是有限的,可改变的。),添加指定的描述符到集合,就是置描述符数据所对应的比特位为1。

nfds:最大的描述符,select将集合拷贝到内核,然后轮循(循环判断一遍有没有就绪的描述符,没有就过一会儿再来轮循)监控。只轮循到nfds+1的位置处。

select在服务器程序中的应用

多路转接:对大量描述符进行事件阻塞监控,当描述符状态改变(可读、可写、异常),则返回。select创建了三个描述符集合分别监控可读事件、可写事件、异常事件。
在这里插入图片描述
将集合中的数据拷贝到内核,进行阻塞监控(间隔时间,轮循遍历,判断是否有描述符就绪)
如果遍历没有描述符就绪,判断是否超时,超时则会返回0。如果有描述符就绪,将集合中没有就绪的无关描述符从集合中移除(集合中剩下的都是就绪描述符)。

读事件就绪

  • socket内核中, 接收缓冲区中的字节数, 大于等于低水位标记SO_RCVLOWAT. 此时可以无阻塞的读该文件描述符, 并且返回值大于0;
  • socket TCP通信中, 对端关闭连接, 此时对该socket读, 则返回0;
  • 监听的socket上有新的连接请求;
  • socket上有未处理的错误;

写事件就绪

  • socket内核中, 发送缓冲区中的可用字节数(发送缓冲区的空闲位置大小), 大于等于低水位标记
    SO_SNDLOWAT, 此时可以无阻塞的写, 并且返回值大于0;
  • socket的写操作被关闭(close或者shutdown). 对一个写操作被关闭的socket进行写操作, 会触发SIGPIPE信号;
  • socket使用非阻塞connect连接成功或失败之后;
  • socket上有未读取的错误;

异常事件就绪

  • socket上收到带外数据. 关于带外数据, 和TCP紧急模式相关。

select优缺点

Select缺点:

  1. 能够监控的描述符有最大上限(因为位图最大取决于FD_SIZE)
  2. 将fd加入select监控集的同时,还要再使用一个数据结构array保存放到select监控集中的fd。
    一是用于再select 返回后,array作为源数据和fd_set进行FD_ISSET判断。
    二是select返回后会把以前加入的但并无事件发生的fd清空,则每次开始select前都要重新从array取得。
  3. 因为select每次都需要将集合数据拷贝到内核,并且在内核是轮循遍历实现监控,因此性能随着描述符增多而降低。

Select优点:

  1. 可跨平台。
  2. 超时时间控制比较精细,可以控制到微秒。
发布了139 篇原创文章 · 获赞 55 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/Vickers_xiaowei/article/details/89341366