通俗易懂说多路复用(1)select

1. 什么是多路复用?

1.1 定义

多路复用就是通过一种机制,可以监听多个描述符,一旦某个描述符就绪(可以读/写),就通过某种方法通知相应程序进行相应操作。
(其中,**文件描述符(fd)**是一个整数,起到一个索引的作用。进程通过fd找到fd指向的文件指针,从而对文件进行操作。)

1.2 通俗易懂的举例

假设你在家一边玩游戏过程中,水壶正在烧水,洗衣机同时在洗衣服。不久,游戏过程中,水壶响了,你就去倒水;洗衣机洗好了,你就去晾衣服。你通过听它们的响声“滴滴滴”来判断事情有没有完成,然后进行下一步操作。
在这里水壶烧水,洗衣机洗衣服就分别是一个文件描述符;
他们任务完成了,发出“滴滴滴”的响声,就是描述符就绪了,通知你可以进行操作了。
多路复用在这里就是有许多家务在进行着,其中你对多项任务进行监听,通过某种方法来判断它们有没有完成,从而进行下一步操作。

1.3 种类

多路复用的方法有:select,poll,epoll

2. 什么是select?

2.1 背景

1. 原始处理方式:
在select,poll,epoll出现之前,最初处理多路复用的方法是:通过非阻塞忙轮询I/O的方式处理多个描述符(流)
2. 特点: 不停的从头到尾地轮询所有描述符/流
3. 缺点: 如果所有的流都没有数据,cpu空转,浪费cpu资源
4. 伪代码:

while true{ //一直轮询多有流
	if i in streams[] { //如果有描述符就绪,就进行处理
		read until unavailable
	}
}

2.2 定义

1. 定义:
为了解决原始处理方式的cpu空转浪费资源问题,引入了一个代理叫做select。select 通过同时监听多个描述符/流,在空闲的时候,把当前处理线程阻塞掉,当有一个或多个描述符/流就绪的时候,就从阻塞状态中醒来进行处理。
2. 优点: 只需要轮询一遍流,就知道有描述符就绪;
3. 缺点: 知道描述符就绪,但是不知道是具体的哪个就绪,所以需要轮询找出具体的描述符/流。
4. 复杂度: O(n)
5. 伪代码:

	while true{ //一直轮询
		select (streams[]) { //select  阻塞,监听所有描述符
			if i in streams[] { //遍历,找出就绪的描述符进行处理
				read until unavailable
			}
		}
}

3. 参考:

我读过的最好的epoll讲解 -知乎

猜你喜欢

转载自blog.csdn.net/lqy971966/article/details/89173936