【Linux网络】select函数


欢迎来到 破晓的历程的 博客

⛺️不负时光,不负己✈️


文章目录

select函数介绍

在Linux网络编程中,select 函数是一种非常有用的IO多路复用技术,它允许程序监视多个文件描述符(file descriptors),以等待一个或多个文件描述符变得"就绪"(ready),比如有数据可读、写操作可能不阻塞或者出现了异常条件。这对于提高网络服务器等需要同时处理多个网络连接的应用程序的效率至关重要。

cpp 复制代码
#include <sys/select.h>  
#include <sys/time.h>  
#include <unistd.h>  
  
int select(int nfds, fd_set *readfds, fd_set *writefds,  
           fd_set *exceptfds, struct timeval *timeout);

select()函数允许程序监视多个文件描述符,等待所监视的一个或者多个文件描述符变为"准备好"的状态。所谓的"准备好"状态是指:文件描述符不再是阻塞状态,可以用于某类IO操作了,包括可读,可写,发生异常三种

select函数参数介绍

nfds

select函数一次会等待多个文件描述符,nfds通常为设置的最大文件描述符+1

fd_set

readfds和writefds,exceptfds的类型都是fd_set,那么fd_set类型是什么呢?
**fd_set本质是一个位图结构!**比特位的位置代表对应的文件描述符,比特位的数值表示对应的文件描述符是否需要关心:1表示该位置的文件描述符需要关心,0表示该位置的文件描述符不需要关心。

为了方便对该结构进行相关的操作,操作系统也给我们准备了相关的函数:

cpp 复制代码
       void FD_CLR(int fd, fd_set *set);
       //将某个文件描述符从位图中取消
       int  FD_ISSET(int fd, fd_set *set);
       //判断某个文件描述符在位图中是否被设置
       void FD_SET(int fd, fd_set *set);
       //将某个文件描述符设置进位图中
       void FD_ZERO(fd_set *set);
       //清空位图

readfds

这个参数为输入输出型参数,表示等待读事件的文件描述符集合。如果不需要关心有哪些文件描述符已经就绪,则可将该参数设置为nullptr

该参数为输入输出型参数:

  • 输入:我们将想要关心的文件描述符通过参数的形式传给内核函数。
  • 输出:等到函数醒来后,函数会将就绪的文件描述符设置进位图中,然后返回给上层

notice :第三个参数和第四个参数和第二个参数都是一样的,只不过第三个参数表示写就绪,第四个参数表示检查异常条件

timeout

该参数的类型为该结构体

cpp 复制代码
struct timeval
  {
    __time_t tv_sec;		/* Seconds.  */
    __suseconds_t tv_usec;	/* Microseconds.  */
  };

select函数返回值

  • 成功时,select返回就绪的文件描述符的总数.
  • 如果在超时前没有任何文件描述符就绪,则返回0.
  • 出错时,返回-1,并设置errno以指示错误.

select的工作流程

应用进程和内核都需要从readfds和writefds获取信息,其中,内核需要从readfds和writefds知道哪些文件描述符需要等待,应用进程需要从readfds和writefds中知道哪些文件描述符的事件就绪.

如果我们要不断轮询等待文件描述符,则应用进程需要不断的重新设置readfds和writefds,因为每一次调用select,内核会修改readfds和writefds,所以我们需要在 应用程序 中 设置一个数组 来保存程序需要等待的文件描述符,保证调用 select 的时候readfds 和 writefds中的将如下:

TCP服务器【多路复用版】

如果是一个select服务器进程,则服务器进程会不断的接收有新链接,每个链接对应一个文件描述符,如果想要我们的服务器能够同时等待多个链接的数据的到来,我们监听套接字listen_sock读取新链接的时候,我们需要将新链接的文件描述符保存到read_arrys数组中,下次轮询检测的就会将新链接的文件描述符设置进readfds中,如果有链接关闭,则将相对应的文件描述符从read_arrys数组中拿走。

相关推荐
小-黯4 分钟前
Ubuntu离线安装软件包
linux·运维·ubuntu
学不动CV了14 分钟前
C语言(FreeRTOS)中堆内存管理分析Heap_1、Heap_2、Heap_4、Heap_5详细分析与解析(二)
linux·c语言·arm开发·stm32·单片机·51单片机
tt55555555555528 分钟前
Linux驱动开发核心概念详解 - 从入门到精通
linux·运维·驱动开发
laolitou_10245 小时前
CentOS 7安装部署RabbitMQ
linux·centos·rabbitmq
独行soc5 小时前
2025年渗透测试面试题总结-97(题目+回答)
网络·安全·web安全·adb·面试·渗透测试·安全狮
aitav06 小时前
⚡ WSL2 搭建 s5p6818 Linux 嵌入式开发平台 (part 3):Wifi驱动移植、ssh移植、e2fsprogs移植
linux·wifi·ssh·嵌入式·e2fsprogs
Elastic 中国社区官方博客6 小时前
Elasticsearch MCP 服务器:与你的 Index 聊天
大数据·服务器·人工智能·elasticsearch·搜索引擎·ai·全文检索
cpsvps_net6 小时前
VPS服务器锁等待超时处理,如何有效解决数据库性能瓶颈
服务器·数据库·oracle
南枝异客8 小时前
CentOS 7 网络连接问题
linux·运维·centos
H3C-Navigator9 小时前
HRPC在Polaris存储系统中的应用
网络·人工智能·ai-native