简单了解多路转接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集合

相关推荐
bigbig_ben2 小时前
yearning安装docker
运维·docker·容器
日常筹谋记5 小时前
工业厂房 TPO 防水卷材:技术需求如何传导到配方层面?
运维·网络·html
老歌老听老掉牙5 小时前
WorkBuddy 如何接入 PrePoMax 的 MCP 服务器
服务器·ai·mcp
Linux_cy5 小时前
服务器管理工具哪个好用?我用了七八个
运维·服务器·javascript·python·ssh·面板·gmssh
sun_weitao7 小时前
极简版 MCP 工具实现方案
java·linux·服务器
发量惊人的中年网工8 小时前
抗DDoS服务哪家比较靠谱?选DDoS防护服务重点看哪几点?
运维·ddos
Meta Luo9 小时前
页面改版后自动化用例大量失败,应该怎么维护?
运维·功能测试·测试工具·自动化
爱和冰阔落9 小时前
【Linux】线程安全进阶:单例模式、可重入函数与死锁排查
linux·运维·安全·单例模式
dk_tjy9 小时前
迪康网络运维故障自愈的自动化闭环技术路径分析
运维·网络·自动化