Select工作原理

发布时间:2023年12月31日

????????I/O多路复用是一种并发处理的机制,允许一个进程通过一种机制监视多个描述符,从而在有多个I/O操作需要处理时选择其中之一进行服务。select 函数是一种常见的实现 I/O 多路复用的系统调用,它允许一个进程同时监视多个文件描述符的可读性、可写性和异常性。

主要特点和步骤包括:

  1. 构造文件描述符列表:

    • 开发者需要创建一个文件描述符集合,包含所有要监视的文件描述符。
    • 这个集合通过数据结构 fd_set 来表示。
  2. 设置文件描述符状态:

    • 在监视之前,需要设置文件描述符的状态,指明关心的事件,如可读、可写、异常等。
    • 这通过 FD_SETFD_CLR 等宏来实现。
  3. 调用 select 函数:

    • 调用 select 函数,传入文件描述符集合,同时设置超时时间(或一直阻塞)。
    • 调用一个系统函数,监听该列表中的文件描述符,直到这些描述符中的一个或者多个进行 I/O 操作时,该函数才返回。
      a. 这个函数是阻塞
      b. 函数对文件描述符的检测的操作是由内核完成的
  4. 在返回时,它会告诉进程有多少(哪些)描述符要进行I/O操作。

// sizeof(fd_set) = 128 1024
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/select.h>
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
- 参数:
- nfds : 委托内核检测的最大文件描述符的值 + 1
- readfds : 要检测的文件描述符的读的集合,委托内核检测哪些文件描述符的读的属性
- 一般检测读操作
- 对应的是对方发送过来的数据,因为读是被动的接收数据,检测的就是读缓冲
区
- 是一个传入传出参数
- writefds : 要检测的文件描述符的写的集合,委托内核检测哪些文件描述符的写的属性
- 委托内核检测写缓冲区是不是还可以写数据(不满的就可以写)
- exceptfds : 检测发生异常的文件描述符的集合
- timeout : 设置的超时时间
struct timeval {
long tv_sec; /* seconds */
long tv_usec; /* microseconds */
};
- NULL : 永久阻塞,直到检测到了文件描述符有变化
- tv_sec = 0 tv_usec = 0, 不阻塞
- tv_sec > 0 tv_usec > 0, 阻塞对应的时间
- 返回值 :
- -1 : 失败
- >0(n) : 检测的集合中有n个文件描述符发生了变化
// 将参数文件描述符fd对应的标志位设置为0
void FD_CLR(int fd, fd_set *set);
// 判断fd对应的标志位是0还是1, 返回值 : fd对应的标志位的值,0,返回0, 1,返回1
int FD_ISSET(int fd, fd_set *set);
// 将参数文件描述符fd 对应的标志位,设置为1
void FD_SET(int fd, fd_set *set);
// fd_set一共有1024 bit, 全部初始化为0
void FD_ZERO(fd_set *set);

?????????select 函数的使用使得一个进程可以同时监视多个文件描述符的状态,而不需要为每个文件描述符创建一个线程或进程。这种方式在网络编程中特别有用,允许处理多个连接而不阻塞整个程序。

文章来源:https://blog.csdn.net/leimeili/article/details/135319151
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。