IO多路复用到底是什么?用生动的例子带你看懂

我发现很多人在面试的时候,都会被问道关于什么select、poll、epoll的问题,但是多路复用IO这一块的知识,大家普遍学得似懂非懂,很多同学甚至不知道这些是多路复用IO里面的知识,而网上写的内容由太过于晦涩难懂,在这里,我用最简单的语言带大家了解一下IO多路复用到底是什么。

一、什么是IO操作

我们都知道在Unix环境下,一切皆文件,而文件就是一串二进制流。在信息 交换的过程中,我们都是对这些流进行数据的收发操作,简称为I/O操作(input and output),往流中读出数据,系统调用read,写入数据,系统调用write。

二、文件描述符

可是在实际操作过程中,计算机里面有那么多流,我们怎么知道该造作的是哪个流呢?于是我们就要依赖文件描述符;
文件描述符就是一个整数,这就有点像我们刚出生的时候,会有一个身份证编号,通过这个编号,我们能够确定一个具体的人;那么同理,我们在Unix系统下,如果打开一个文件,会得到一个文件描述符,以后我们通过这个文件描述符就可以找到这个需要操作的文件,进行操作;

三、什么叫做阻塞

假如你今天在家里做饭,你决定我一定要先烧鱼,可是去买鱼的人就是没有回来,于是你后面的事情都不干了,卡在那里等鱼,这就是阻塞;
你在Unix系统中,如果一定要等一条信息,那条信息不来,你就什么都不干,停在那里了,这就是阻塞;

四、I/O输入输出步骤

输入操作一般包含两个步骤:
1、等待数据准备好(waiting for data to be ready)。对于一个套接口上的操作,这一步骤关系到数据从网络到达,并将其复制到内核的某个缓冲区。
2、将数据从内核缓冲区复制到进程缓冲区(copying the data from the kernel to the process)。

这就像是刚才举的例子,你一定要等到你想要的菜到了,菜干活,于是就有可能堵在那里,于是效率就变得很低;

五、三种I/O模型

1、阻塞I/O模型

最广泛的模型是阻塞I/O模型,默认情况下,所有套接口都是阻塞的。 进程调用recvfrom系统调用,整个过程是阻塞的,直到数据复制到进程缓冲区时才返回(当然,系统调用被中断也会返回)。

(看不懂就看这里)
这就是刚才提到的,如果你买不到鱼,就等在那里,其他的菜也不烧了,于是你做饭的效率就显得非常得低下。

2、非阻塞I/O模型

当我们把一个套接口设置为非阻塞时,就是在告诉内核,当请求的I/O操作无法完成时,不要将进程睡眠,而是返回一个错误。当数据没有准备好时,内核立即返回EWOULDBLOCK错误,第四次调用系统调用时,数据已经存在,这时将数据复制到进程缓冲区中。这其中有一个操作时轮询(polling)。

(看不懂就看这里)
你如果发现买鱼的人没回来,你就知道买鱼这件事情出了问题,于是看看后面的事情,能干啥就干点啥。然后每过一点时间就回过头来看一下,鱼买回来没有,如果买回来了就做鱼,而这个时间剑客就是轮询时间。

3、I/O复用模型

此模型用到select和poll函数,这两个函数也会使进程阻塞,select先阻塞,有活动套接字才返回,但是和阻塞I/O不同的是,这两个函数可以同时阻塞多个I/O操作,而且可以同时对多个读操作,多个写操作的I/O函数进行检测,直到有数据可读或可写(就是监听多个socket)。select被调用后,进程会被阻塞,内核监视所有select负责的socket,当有任何一个socket的数据准备好了,select就会返回套接字可读,我们就可以调用recvfrom处理数据。正因为阻塞I/O只能阻塞一个I/O操作,而I/O复用模型能够阻塞多个I/O操作,所以才叫做多路复用。

(看不懂就看这里)
你水平比较高,一次性观察着所有的菜,如果哪一个菜到了,你就先去烧那个菜;
如果所有菜都没到,你也会卡在那里啥都不干;
这样烧菜的效率就会比较高;

你可能感兴趣的:(Unix环境编程)