I/O多路复用之select

微信公众号:CPP进阶之旅
如果觉得这篇文章对您有帮助,欢迎关注 CPP进阶之旅 学习更多技术干货

1、select函数作用

  select,poll,epoll都是IO多路复用的机制。I/O多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,而异步I/O则无需自己负责进行读写。
  select函数的作用是在一段指定时间内,检测一组用户感兴趣的文件描述符中某个或某几个是否有“事件”,这里的“事件”一般分为如下三类:

  1. 可读事件,一般意味着可以调用recv或read 函数从该 socket 上读取数据;如果该 socket是侦听socket(即调用了 bind 函数绑定过 ip 地址和端口号,并调用了 listen 启动侦听的socket)可读意味着此时可以有新的客户端连接到来,此时可调用 accept 函数接受新连接。
  2. 可写事件,一般意味着此时调用 send 或 write 函数发送数据。
  3. 异常事件,某个文件描述符出现异常。

2、select详细介绍

  • 函数原型
    int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

  • 参数说明
    nfds : 表示指定被监听的文件描述符的总数,这个参数的值通常设置成所有需要使用select函数监听的fd中最大fd值加 1,因为文件描述符是从0开始计数的。
    readfds : 表示需要监听可读事件的 fd 集合。
    writefds : 表示需要监听可写事件的 fd 集合。
    exceptfds : 表示需要监听异常事件的 fd 集合。
    timeout : 表示超时时间,即在这个参数设定的时间内检测这些 fd 的事件,超过这个时间后 select 函数将立即返回。如果timeout设置为null,则select将一直阻塞,直到某个文件描述符就绪。

  • 返回值
    执行成功则返回文件描述符已经就绪(可读、可写、异常)的总数,这时我们可以通过遍历的方式获取到已经就绪的文件描述符。如果在超时时间内没有任何文件描述符就绪则返回0。当有错误发生时则返回-1,错误原因存于errno。如果在select等待期间,程序接收到信号,则select返回-1,并设置errno为EINTR。

  • 其他说明
    程序在调用select时通过readfds、writefds和exceptfds这三个参数传入我们感兴趣的文件描述符。select返回时,内核修改他们来通知哪些文件描述符已经就绪。
    这三个参数的类型都是fd_set结构体,而fd_set结构仅包含一个整形数组,该数组的每个元素的每一位标记一个文件描述符,该数组的大小由FD_SETSIZE指定,linux下一般为1024。
    下面是对readfds、writefds和exceptfds这三种文件描述符集合操作相关的宏:
    FD_CLR(inr fd,fd_set* set);//用来清除fd_set中相关fd 的位
    FD_ISSET(int fd,fd_set set);//用来测试fd_set中相关fd 的位是否为真 FD_SET(int fd,fd_setset);//用来设置fd_set中相关fd的位
    FD_ZERO(fd_set *set);//用来清除fd_set的全部位

3、select注意事项

  1. select函数调用会修改 readfds、writefds 和 exceptfds 这三个集合中的内容,如果下次调用select时需要复用这个变量,需要在下次调用 select 前先使用 FD_ZERO 将集合清零,然后调用 FD_SET 将需要检测事件的fd再次添加进去。
  2. 在调用select函数之后我们需要用FD_ISSET检测文件描述符是否有事件。
  3. select 函数也会修改 timeval 结构体的值,这也要求我们如果像复用这个变量,必须给 timeval 变量重新设置值。

4、select函数缺点

  1. 单个进程可监视的fd数量被限制,即能监听端口的大小有限。
  2. 对文件描述符进行扫描时是线性扫描,即采用轮询的方法,效率较低。
  3. 每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大。

5、重要说明

欢迎大家关注我的个人微信公众号,查看专业的客户端/服务端开发知识、笔试面试题目、程序员职场经验与心得分享。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/siyacaodeai/article/details/113811119