C++ 全栈知识体系C++ 全栈知识体系
✿导航
  • 基础
  • 函数
  • 知识点
  • IO框架
  • 新版本特性
  • 数据库原理
  • SQL语言
  • SQL - MySQL
  • NoSQL - Redis
  • NoSQL - ElasticSearch
  • 算法基础
  • 常见算法
  • 领域算法
  • 分布式算法
  • 数据结构与算法
  • 计算机网络
  • 操作系统
  • 计算机组成
  • 开发
  • 测试
  • 架构基础
  • 分布式系统
  • 微服务
  • 中间件
  • 概念
  • 理论
  • 架构设计原则
  • 设计模式
  • 协议
  • 技术选型
  • 编码规范
  • 流水线构建 - CI/CD
  • 知识点 - Linux
  • 网站 - Nginx
  • 容器化 - Docker
  • 容器编排 - Kubernetes
  • 服务网格 - Service Mesh Istio
  • 常用快捷键 - Shortcut
  • 工具使用 - Tools
  • 开源项目
  • 学习项目
  • 个人项目
  • 项目开发
  • 项目Idea
  • 并发
  • 部署
  • 分布式
  • 知识
  • 问题
  • 编程语言与技术
  • 系统与架构
  • 软件开发实践
  • 数据处理与应用设计
  • 个人
  • 产品
  • 团队
  • 知识体系
  • Vue
关于
✿导航
  • 基础
  • 函数
  • 知识点
  • IO框架
  • 新版本特性
  • 数据库原理
  • SQL语言
  • SQL - MySQL
  • NoSQL - Redis
  • NoSQL - ElasticSearch
  • 算法基础
  • 常见算法
  • 领域算法
  • 分布式算法
  • 数据结构与算法
  • 计算机网络
  • 操作系统
  • 计算机组成
  • 开发
  • 测试
  • 架构基础
  • 分布式系统
  • 微服务
  • 中间件
  • 概念
  • 理论
  • 架构设计原则
  • 设计模式
  • 协议
  • 技术选型
  • 编码规范
  • 流水线构建 - CI/CD
  • 知识点 - Linux
  • 网站 - Nginx
  • 容器化 - Docker
  • 容器编排 - Kubernetes
  • 服务网格 - Service Mesh Istio
  • 常用快捷键 - Shortcut
  • 工具使用 - Tools
  • 开源项目
  • 学习项目
  • 个人项目
  • 项目开发
  • 项目Idea
  • 并发
  • 部署
  • 分布式
  • 知识
  • 问题
  • 编程语言与技术
  • 系统与架构
  • 软件开发实践
  • 数据处理与应用设计
  • 个人
  • 产品
  • 团队
  • 知识体系
  • Vue
关于
  • 基础

    • C++ 基础 - 学习路线
    • C++ 基础 - 知识点
    • C++ 基础 - 面向对象
    • C++ 基础 - 语法糖
    • C++ 基础 - 关键字
    • C++ 基础 - 常用宏定义
    • C++ 基础 - 宏函数、内联函数、普通函数
  • 函数

    • C++ 函数 - 闭包
    • C++ 函数 - Linux系统调用Hook
    • C++ 函数 - getopt函数分析以及命令行解析
    • C++ 函数 - 函数指针及其应用
    • C++ 函数 - 作用域运算符::的使用
    • C++ 函数 - 智能指针shared_ptr的使用
    • C++ 函数 - struct结构体学习
    • C++ 函数 - typedef 语句的使用
    • C++ 函数 - va_list函数学习
  • 知识点

    • C++ 知识点 - 写时拷贝技术(copy-on-write)
    • C++ 知识点 - 前向声明(forward declaration)
    • C++ 知识点 - 头文件.h 和 源文件.cpp 以及多重定义(multiple definition)
    • C++ 知识点 - 为什么C语言不支持函数重载,C++又是如何支持的
    • C++ 知识点 - return 局部变量
    • C++ 知识点 - linux下c/cplusplus头文件和动态库的搜索
    • C++ 知识点 - 模板特化与偏特化
  • IO框架

    • C++ IO框架 - I/O 复用
    • C++ IO框架 - select 函数
    • C++ IO框架 - poll 函数
    • C++ IO框架 - epoll 函数
    • C++ IO框架 - Reactor 和 Proactor
  • 新版本特性

    • C++ 新版本特性 - C++11
    • C++ 新版本特性 - C++14
    • C++ 新版本特性 - C++17
    • C++ 新版本特性 - C++20

C++ IO框架 - select 函数

  • 概述
  • 详细解析

概述

该函数允许进程指示内核等待多个事件中的任何一个发生,并只在有一个或多个事件发生或经历一段指定时间后才唤醒它。 (主旨思想:不再由应用程序自己监视客户端连接,取而代之由内核替应用程序监视文件。)

详细解析

函数内容详解:

#include <sys/select.h>
/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
int select(int maxfdpl, fd_set *readset, fd_set *writeset,
			fd_set *exceptset, struct timeval *timeout);

	maxfdpl: 	监控的文件描述符集里最大文件描述符加1,因为此参数会告诉内核检测前多少个文件描述符的状态
	readset: 	监控有读数据到达文件描述符集合,传入传出参数
	writeset: 	监控写数据到达文件描述符集合,传入传出参数
	exceptset: 	监控异常发生达文件描述符集合,如带外数据到达异常,传入传出参数
	timeout: 	定时阻塞监控时间,3种情况
				1.NULL,永远等下去
				2.设置timeval,等待固定时间
				3.设置timeval里时间均为0,检查描述字后立即返回,这称为轮询
	struct timeval {
		long tv_sec; /* seconds */
		long tv_usec; /* microseconds */
	};

    void FD_ZERO(fd_set *set); 			 //把文件描述符集合里所有位清0
    void FD_SET(int fd, fd_set *set); 	 //把文件描述符集合里fd位置1
	void FD_CLR(int fd, fd_set *set); 	 //把文件描述符集合里fd清0
	int  FD_ISSET(int fd, fd_set *set);  //测试文件描述符集合里fd是否置1

注意事项:

  • select能监听的文件描述符个数受限于FD_SETSIZE,一般为1024,单纯改变进程打开的文件描述符个数并不能改变select监听文件个数;
  • 描述符就绪条件:
    • 当某个套接字上发生错误时,它将由select标记为既可读又可写;
    • 接收低水位标记和发生低水位标记目的在于: 允许应用进程控制select返回可读或可写条件之前有多少数据可读或有多大空间可用于写。
      • 例如至少存在64字节的数据准备好读时select唤醒我们,从而避免频繁打断应用进程处理其他工作。

select总结:

优点:

  • select 遵循posix标准,跨平台移植性较好;
  • select监控的超时等待时间,可以精细到微秒;

缺点:

  • select所能监控的描述符是有最大上限的,取决于宏_FD_SETSIZE,默认大小为1024;
  • select的监控原理是在内核中进行轮询遍历,这种遍历会随着描述符的增多而性能下降;
  • select返回的时候会移除所有的未就绪描述符,给用户返回就绪的描述符集合,但是没有直接告诉用户那个描述符就绪,需要用户自己遍历才能获知那个描述符在集合中,操作流程比较麻烦;
  • select每次监控都需要重新将集合拷贝到内核中才能进行监控;
  • select每次都返回都会移除所有未就绪的描述符,因此每次监控都要重新向集合中添加描述符;
Last Updated:
Contributors: klc407073648
Prev
C++ IO框架 - I/O 复用
Next
C++ IO框架 - poll 函数