简单了解多路转接select

多路转接的核心含义是:用一个执行流(线程/进程),同时管理多路 IO通道,把就绪的通道"转接"出来处理

多路转接有三种实现方式:select/ poll / epoll

多路转接将IO操作的等待+拷贝两个环节,在操作方式上也进行了划分

上面列举的三种实现方式,负责的就是等的环节。本环节的任务就是让单个执行流一次可以等待多个fd

本篇将会重点了解一下select

select基本结构

一共有五个参数

nfds :等的多个fd中,值最大的+1(比如若等待的fd为 1、3,nfds就是4)

timeout :等待方式(有三种)

1、NULL select一直被阻塞直到某个文件描述符上发生了事件

2、{0} 只会检查一遍有没有fd就绪,然后立即返回,不进行阻塞等待

3、特定的时间值 如果在指定的时间内没有fd就绪,select超时返回

timeout 是输入输出型参数,内核每次调用select都会修改timeout,减去已经消耗的时间。

比如如果指定 等待3秒钟,若在第1秒有fd就绪了,内核就会将timeout设置成为2秒,意味着还剩下2秒钟

返回值

1、执行成功返回文件描述符已经就绪的个数

2、返回0 代表已经超过timeout时间且没有文件描述符就绪

3、若有错误发生返回-1,错误原因存于errno

文件描述符上无非只有三种就绪:读事件就绪(有数据到来)、写事件就绪(有空间可以进行拷贝)、异常事件就绪(出现TCP带外数据等异常情况)

为了区分不同事件,select设置了三种不同的集

分别为 读事件集、写事件集、异常事件集

想让select关心哪个事件,就把对应的文件描述符设置到对应的集里面(参数里)

fd_set类型字段代表的 就是文件描述符集

fd_set底层其实就是一个具有 1024位的位图(每一位就代表一个fd)

readfds :它是一个输入输出型参数,用来表示 读事件集

1、作为输入的时候,用来设置对什么文件描述符关心(1代表关心,0代表不关心)

2、作为输出的时候,内核用来通知用户哪些fd就绪了(1代表就绪,0代表没有就绪)

需要注意的是:内核只会关心用户要求关心的fd,若不关心的fd就绪了,不会通知用户该fd就绪

writefds 为写事件集、exceptfds为 异常事件集。与readfds情况一致

select操作位图的接口

其中FD_ZERO是用来清空事件集的,由于select内事件集既可以作为用户关心的fd列表,也可以作为内核反映底层fd就绪的列表,所以每次select之前事件集都需要进行一次FD_ZERO,避免部分已经关闭的fd继续残留在 集合里

select原理 以及 优缺点

select 底层是采用遍历的方式进行检测fd是否就绪。这也就是为什么select的第一个参数是关心的最大的fd+1

每一个文件描述符表里都有一个函数指针表,里面有一个指向poll函数,内核可以通过这个poll函数来确定该文件描述符是否就绪。如果就绪就将集合内 fd 对应位置置1,没有就绪就将进程挂到这个fd的等待队列内

如果遍历完发现select内部有fd就绪,内核就会将进程(entry)从所有的等待队列里摘出来,然后将进程放进运行队列(一个进程不能即在等待队列又在运行队列),返回给用户已就绪的fd

如果遍历完发现select内部没有一个fd就绪,进程就会进入睡眠状态,直到有fd就绪,进程才会被内核唤醒。唤醒后内核就会重新将事件集遍历一遍,然后将就绪的所有fd返回给用户

select 优点:

单进程处理多连接,聚合fd,提高IO效率

select 缺点

1、底层采用的是遍历,尽管文件描述符越多等的比重越低,也依然会因为遍历周期过多,导致效率不高

2、内核和用户之间状态转变导致的拷贝次数过多

3、支持的文件描述符数量太少

4、每次都要手动设置fd集合

相关推荐
2302_1111 小时前
java依赖小结
java·运维·数据库
程序员-Benothing2 小时前
Shell 脚本条件判断与流程控制:if for while case 详解
linux·运维·服务器
captain3762 小时前
网络原理(3)-TCP核心机制连接管理▲▲▲
java·服务器·网络·ide·网络协议·tcp/ip·java-ee
君生我老2 小时前
Linux动静态库
linux·服务器
troy1282 小时前
Python 基础语法(一):变量、数据类型与运算符
java·服务器·python
IT摆渡者2 小时前
基于 Docker 部署 Nextcloud 私有云盘(外挂 Windows 共享)项目实践
运维·docker·容器
程序员清风3 小时前
记忆系统设计:让 Agent 拥有短期记忆与长期记忆
java·服务器·网络
做运维的阿瑞3 小时前
Linux下DNS服务器搭建
linux·运维·服务器
团子股股东峥哥3 小时前
day37-RHEL-管理基本存储
linux·运维·服务器