温馨提示:这篇文章已超过453天没有更新,请注意相关的内容是否还可用!
摘要:本文介绍了四种网络IO模型,包括阻塞式IO模型、非阻塞式IO模型、IO多路复用模型以及异步IO模型。这些模型在网络编程中各有优劣,适用于不同的场景和需求。了解这些模型有助于开发人员提高网络应用程序的性能和响应能力。
五敷有你
系列专栏:面经
⛺️稳中求进,晒太阳
IO的定义
IO是计算机内存与外部设备之间拷贝数据的过程,由于CPU访问内存的速度远高于外部设备,因此CPU会先把外部设备的数据读取到内存,再进行处理。
大家是否还记得局部性原理:
时间局部性
空间局部性
在一次IO操作中,通常会一次性加载一块数据或其附近的数据到内存中。
IO的流程
用户发起调用操作,通过系统调用函数read()来间接地调用系统内核,从网卡读取数据,数据首先被读取到内核缓冲区,然后从内核缓冲区拷贝到用户态内存缓冲区。
为什么要有内核态与用户态?
早期的计算机设计并没有这个设计思想,由于一些指令具有高风险性,如果误用可能导致整个系统崩溃,为了避免直接由用户操作这些敏感操作,内核态与用户态的概念被引入。
内核态处于内核态的CPU可以任意访问数据,包括外围设备如网卡、硬盘等,内核态的CPU可以在一个程序切换到另一个程序时,不发生CPU资源的抢占,处于特权级0的状态被称为内核态。
用户态处于用户态的CPU只能访问受限制的资源,不能直接访问内存等硬件设施,必须通过系统调用陷入内核态中,才能访问这些特权资源。
内核缓冲区处理的是内核空间和磁盘之间的数据传递,目的是减少访问磁盘的次数;而用户缓冲区处理的是用户空间和内核空间的数据传递,目的是减少系统调用的次数。
IO要解决的问题
在这个过程中涉及到的CPU操作、内存操作、外部物理设备的操作,由于三者数据处理速度的差异,用户读取数据时可以采用以下两种方式:用户线程阻塞等待或非阻塞轮询并读取数据,这就是IO模型需要解决的问题。
四种主要的IO模型
1、同步阻塞IO:
用户线程发起read调用后阻塞,让出CPU,内核态等待网卡数据到来,把网卡数据拷贝到内核空间,接着把数据拷贝到用户空间,然后唤醒用户线程。
2、同步非阻塞IO:
将Socket设置为non-blocking状态后,当前连接变成非阻塞IO,在同步非阻塞IO中,如果内核缓冲区没有数据,系统调用会立刻返回并告知调用失败,这样的请求不会阻塞,用户线程需要不断发起IO系统调用以测试内核数据是否准备好,如果内核缓冲区有数据且准备就绪则是阻塞的,直到内核缓冲区的数据全部复制到进程缓冲区,系统调用完成,同步非阻塞IO模型的特点是程序需要不断发起IO系统调用进行轮询。
3、IO多路复用模型:引入select/epoll系统调用以查询IO的就绪状态,通过该系统调用可以监视多个文件描述符,一旦某个描述符就绪(一般是内核缓冲区可读可写),内核就能将就绪状态返回给应用程序进行相应IO操作,在IO多路复用模型中通过select/epoll系统调用实现单个应用程序线程不断轮询多个socket连接的状态并进行相应的读写操作一旦某个或者某些socket网络连接就绪就可以立即进行读写操作而无需等待其他连接完成读写操作IO多路复用模型的特点是需要轮询就绪状态查询系统调用的线程需要不断轮询以找出达到IO操作就绪的socket连接进行读写操作同时它也需要结合同步阻塞IO或同步非阻塞IO模型来完成实际的读写操作,4. 异步IO模型(AIO):基本流程为用户通过系统调用向内核注册某个IO操作内核在整个IO操作完成后通知用户程序执行后续的业务操作类似于回调函数在异步IO模型中整个内核的数据处理过程中包括内核将数据从网络物理设备网卡读取到内核缓存区以及将内核缓冲区的数据复制到用户缓冲区用户程序都不需要阻塞当内核的IO操作完成后会通知应用程序进行读数据异步IO模型的特点是用户线程在整个过程中都是非阻塞的在等待数据和复制数据的两个阶段都不需要等待当数据准备就绪后即可进行读写操作无需等待其他操作完成。
希望这次的修改和补充能更好地帮助您表达您的想法!
还没有评论,来说两句吧...