BIO、NIO、epoll、AIO

早期BIO ,blockingIO,阻塞IO。Linux下一切皆文件,socket即读文件描述符(fd)。当建立多个连接时,如下图。

例如fd 8 的client连接一直没返回,导致 read  fd8会进行阻塞,一直等待返回。read fd9连接无法进行处理。

由于BIO 导致阻塞,进而演变成NIO

开始进入NONBLOCK时代,非阻塞。还是多个连接。

非阻塞了,当多个连接来时,进行while 循环,循环调用 fd8 fd9 read,判断有没有返回,有就处理,没有继续循环。

解决了BIO的问题,但是问题又来了。如果有1000个连接,就需要不断地循环1000,从fd1 到fd1000,效率多低。

进而演变内核发展,提供 select 调用。 select接口开始,不用做循环了,直接把fd1到fd1000全部传给select,进行监控,直到有一个或多个的返回,将有返回的fd描述符传给线程去read对应的描述符返回信息。即多路复用NIO时代

虽然进入了多路复用,但是过程很复杂,需要调用select,然后根据返回再去read。尤其是1000个描述符需要从用户态拷贝给select。

内核发展出epoll,用户空间可以调用epoll的create时,内核返回一个epfd(epoll的描述符),当用户空间有一个连接进来后,将连接交给epoll描述符,同时调用epoll的wait(),epoll会准备一个共享空间mmap,只需要维护一个红黑树,连接都放到红黑树里面。共享空间里面增删改由内核完成,用户空间和内核双方都可以查询。当共享空间有连接返回后,wait()就可以返回了,从阻塞变成不阻塞,取出到达的那些描述符,单独去read。

相当于用户空间注册一个连接到内核的epoll共享空间中,连接有返回后进行回调,由内核通知用户空间,再去read描述符。

mmap:共享空间。由内核实现。相当于用户态和内核态之间出现了一个共享空间。

AIO

AIO:Asynchronous IO 是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。但是NIO的IO行为还是同步的

对AIO来说,则更加进了一步,它不是在IO准备好时再通知线程,而是在IO操作已经完成后,再给线程发出通知。因此AIO是不会阻塞的,此时我们的业务逻辑将变成一个回调函数,等待IO操作完成后,由系统自动触发。

猜你喜欢

转载自blog.csdn.net/dandanforgetlove/article/details/106223339