网络IO模型

网络IO模型,第1张

网络IO模型 网络IO 基础知识: TCP协议:

面向连接的可靠的网络协议

三次握手:

客户端向 服务端发起请求 seq, 服务端收到请求后 向服务端返回 seq + ack ,客户端收到服务端发回的请求后 向服务端发送 ack。自此三次握手完成,此后双方会开辟资源

socket:

一个四元组包含了 ClientIP + Cport + SserverIP + Sport 开辟资源后 会加上文件描述

IO层面的同步、异步、阻塞、非阻塞

同步:read/write *** 作需要 application 进行 *** 作

异步:read/write *** 作不需要application进行 *** 作

组合: 同步阻塞(BIO) 、同步非阻塞(NIO)、异步非阻塞(AIO)

下面我们只讨论BIO/NIO

网络IO模型 BIO:同步阻塞

accept / read 都会阻塞,此时主线程会抛出大量的线程。影响效率

NIO:同步非阻塞

NIO :accept/read时不会阻塞。可以通过一个或n个线程解决开辟线程的问题

1.但是每循环1次 都需要遍历请求的socket是否就绪,时间复杂度为O(n)。有很多的调用是无效的调用

2.每次遍历都需要用户态内核态的切换,影响性能

如何解决上述问题

多路复用器:

多路复用的理解

多路:多个文件描述符

复用:公用一个接口,用户只需要有限次的用户态内核态的切换,就能取到已经准备好的资源

Select/Poll

select 和 poll的方式类似,最大的区别 select收到最大文件描述符数量影响。poll不受影响

用户态将需要查询的文件描述符 fds 传给 select/poll 由select/poll 进行状态查询,并返回已经准备好的文件描述符

app 根据结果fds 进行对应的 *** 作

epoll

基于消息通知的多路复用

针对select/poll 我们可以发现每次都要重新传递fds,每次被调用后针对这次调用,触发遍历全量的复杂度。也有很多没必要的查询

其实在内核中,如果fds状态改变,内核是能感知到的。如果在感知到的同时,将fds存储下来,下次app查询时,直接将准备好的数据传回去,这样会大大的提高效率。

主要的三个函数:

epoll_create: 函数生成一个epoll专用的文件描述符。它其实是在内核申请一空间,用来存放你想关注的socket fd上是否发生以及发生了什么事件

epoll_ctl:fds集合 并且会以红黑树的形式存储。

epoll_wait:当某个文件描述符事件触发,会将该事件复制到内存中的一个链表中,等下次函数被app调用时,直接返回即可

扩展:

Redis底层网络模型正是使用了epoll的方式,这也是redis为什么快的原因之一。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/4027297.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-10-22
下一篇2022-10-22

发表评论

登录后才能评论

评论列表(0条)

    保存