5种IO模型的原理

30 篇文章 0 订阅
4 篇文章 0 订阅

阻塞IO,非阻塞IO,IO多路复用,信号驱动IO,异步IO是五种常见的IO模型。

那么他们有什么区别?

我下面以unix的实现过程来说明,他们的实现原理和区别。

阻塞IO

当进程(用户空间)调用recvfrom命令,其系统调用将会一直阻塞,直到recvfrom命令返回或执行过程报错。具体阻塞过程分为:等待数据到达内核空间,数据从内核空间复制到用户空间。
在这里插入图片描述

非阻塞IO

由于内核是否准备好数据,是可以通过recvfrom查询得到的,如果数据没有准备好,会返回一个错误EWOULDBLOCK,我们可以通过轮训该错误码来判断数据是否准备好,从而避免等待数据准备部分的阻塞,从而实现非阻塞IO。
在这里插入图片描述

IO多路复用

IO多路复用是在阻塞IO的基础上,使用select或poll方法,同时传入多个文件描述符。这样select会阻塞等待其中的一个数据准备好,变得可读,再执行将数据从内核空间拷贝到用户空间的过程。
传入单个描述符时,跟阻塞IO没有大的区别,都是全程阻塞的。优势在于传入多个文件描述符时,一个进程可以管理多个文件描述符。
在这里插入图片描述

信号驱动IO

如果当内核准备好数据时,主动通过某种信号机制,告诉我们。这样我们不就可以避免轮训,也能实现等待数据时期的非阻塞了吗。对,这就是信号驱动IO。
具体操作是,首先开启套接字的信号驱动IO功能,并通过系统调用安装一个信号处理函数。该系统调用会立即返回,并不阻塞。当数据在内核中准备好时,内核就为进程产生一个信号,调用信号处理函数,从而实现信号通知。
在这里插入图片描述

异步IO(AIO)

信号驱动IO还是需要用户进程调用recvfrom系统调用,并等待数据拷贝到用户进程。如果系统可以在数据拷贝完成时通知我们,而不是内核准备好数据时通知我们,岂不是更方便。这就是AIO。
我们调用aio_read函数(POSIX异步I/O函数以aio_或lio_开头),给内核传递描述字、缓冲区指针、缓冲区大小(与read相同的三个参数)、文件偏移(与lseek类似),并告诉内核当整个操作完成时如何通知我们。该系统调用立即返回,在等待I/O完成期间,我们的进程不被阻塞。
在这里插入图片描述

各种IO模型的比较

在这里插入图片描述

总结

阻塞IO,阻塞内核准备数据和从内核空间拷贝数据到用户空间两个流程。
非阻塞IO,通过轮训,不阻塞内核准备数据阶段。
IO多路复用,传入多个文件描描述符,从而一个进程管理多个阻塞IO。
信号驱动IO,通过回调函数注册,实现避免轮训,又内核主动通知用户进程。避免内核准备时期的阻塞和轮训。
异步IO,将内核主动通知改到数据复制完成时,从而实现全程无阻塞。
前四种IO模型都需要用户进程参与数据从内核拷贝到用户空间,只有AIO实现了全程的不阻塞。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值