说说什么是IO多路复用?以及其演进过程。 |
您所在的位置:网站首页 › 程序io和中断io的区别是什么 › 说说什么是IO多路复用?以及其演进过程。 |
文章目录
1.阻塞IO模型(BIO)和 非塞IO模型(NIO)2.什么是IO多路复用?3.IO多路复用的演进?
1.阻塞IO模型(BIO)和 非塞IO模型(NIO)
阻塞IO模型(BIO): 如果我们为每一个连接创建一个线程,连接结束时做对应的销毁,这种情况下,如果连接中没有数据可读的话,线程就不得不阻塞,直到连接可读。这个时候就算其他的连接有数据可读,阻塞的线程也是没有机会去处理的。 服务端整个过程只有一个线程,依次循环处理客户端的socket,这种情况下,客户端的某个socket阻塞住了,是会影响到其他的客户端的处理的,必须等待阻塞的客户端处理结束才能接着处理接下来的请求. 非塞IO模型(NIO): 在线程读取数据的时候,如果数据不可读,线程会立即拿到返回,然后去处理别的逻辑。等一会线程再尝试读取数据,这样反复处理,这里就需要一个轮询的逻辑,因为读数据的一端,也不知道数据什么时候可读,所以就需要每间隔一段时间去看看。 非塞IO模型(NIO)相较于阻塞IO最大的特点就是同步非阻塞在进行系统调用的时候,也就是accept和read调用的时候,是不会被阻塞的。socket的相关操作(read、write)都是需要在内核态进行完成的,不能在用户态进行完成,内核态通过将这些函数进行封装,通过像read跟write这种函数提供出来 优点:单个socket阻塞的话,是不会影响到其他的socket 缺点:要不断的在客户端遍历需要建立连接的fd,不断的进行系统调用(会涉及到用户态和内核态的切换),需要一定的开销的。 2.什么是IO多路复用?IO多路复用(出发点就是要设计一个高性能的网络服务器,这个网络服务器可以供多个客户端建立连接,并且能处理多个客户端的请求。。能想到的就是写多线程去处理,其实现在很多的rpc框架就是用到了这种方式,多线程的弊端就是需要不断地进行上下文的切换,需要处理一些上下文的切换(占用内存的瓶颈),这个过程很繁琐,并且会造成资源的浪费,比如有一千个客户端和服务端建立连接,就需要创建一千个线程,但在同一时刻可能就只有三四个建立连接,这就会造成资源的浪费,因而多线程并不是一种最好的解决方式,那么如何用单线程的方式处理): 就是一个线程如何处理多个连接请求的过程和技术,我们不需要为每个连接创建一个处理线程等待数据可读或可写,IO多路复用会在IO准备好的时候主动通知我们,我们用一个线程就可以完成对全部IO通讯的很监听。。IO多路复用被用来解决性能的问题,解决的办法1:资源复用,多个网络IO复用一个或者多个线程来处理请求. 2.线程不需要等待时间被触发,IO事件被触发的时候能直接通知应用程序,要实现这种线程池的处理方式,就需要引入了一个中间层,所有网络连接在中间层上进行注册,而程序也需要阻塞在这个中间层上,等待他的事件通知,这个中间层便是经常提及的SELECT、EPOLL。 FD:文件描述符,非负整数。linux下一切皆文件,linux中的一切资源都可以通过文件的方式访问和管理,fd就是文件的索引,指向某个文件资源,内核利用fd来访问和管理资源。 同步阻塞:服务端每次只会和一个客户端建立连接,要么就阻塞等待,客户端建立连接 同步非阻塞:服务端每次只会和一个客户端建立连接,他不会被阻塞,如果没有就绪的事件时,非阻塞IO会马上返回一个负数的fd,如果服务端没有和客户端建立上连接,他会返回一个非负的fd继续进行轮询,见下图 总结:同步非阻塞IO其实就是操作系统底层,对同步阻塞IO做了一些优化,提供了一种解决问题的方式,从而避免了单个socket影响到其他socket的情况 缺点:同步非阻塞IO需要我们在用户空间不断的去遍历(涉及到用户态到内核态的一个调用,会是一个问题)调用read函数来检查是否有数据到来。 ![]() ![]() ![]() ![]() epoll主要有三个函数,epoll_create(int size),创建一个epoll,size是epoll想要监听的文件符的数量,返回值就是epoll对应的文件描述符,后面我们可以通过返回的文件描述符来操作我们这个epoll。 第二个函数就是epoll_ctl,就是对我们创建的epoll进行操作。 epoll创建之后,底层内核空间是一个eventpoll,有三个元素,等待队列、就绪队列、红黑树 红黑树的话就是把想要监听的这些文件描述符通过红黑树的形式存储起来,通过红黑树进行高效的新增、删除、查询, 就绪列表:就是说如果有一些fd对应的socket已经是就绪的,就是数据已经到来了,这个时候就要把对应的fd添加到就序列表来,可以很快的知道就绪队列 等待队列:当我们调用的时候发现没有事件就绪,这个时候,我们就将我们的进程进行阻塞,阻塞的时候我们就会把这个进程关联到我们的这个等待队列里面,以便后续有事件到来的时候唤醒我们的进程。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |