linux下的常用I/O模型

linux下大概有同步阻塞、同步非阻塞、异步阻塞和异步非阻塞四种I/O模型,在详解介绍这四种模型之前,先分别介绍同步与异步、阻塞与非阻塞的区别。

这里拿生活中的一些现象例子来说明它们之间的区别会比较形象易懂。

同步与异步

在学校食堂排队等候打饭,必须等到队列前面没人了才会轮到自己,这种场景就是同步。如果换成去餐馆,不需要排队直接点菜,菜好了之后服务员直接给我们送上来,这种场景就是异步。异步与同步之间的区别就是消息是如何通知的,在上面场景中,排队打饭需要自己去关注是不是轮到我们了,而餐馆点菜是由服务员通知我们菜好了。

所以说在同步的情况下,是由处理消息者自己去等待消息是否被触发,而在异步情况下,是由触发机制来通知处理消息者,所以在异步情况下,需要一个触发机制,在linux中的常用select/poll等IO多路复用机制中就是fd(文件描述符),触发机制就是通过fd找到处理该fd的函数。

阻塞与非阻塞

无论是排队打饭还是餐馆点菜,如果在等候过程中不能做其它事,这种情况就是阻塞;当然实际的情况是我们在等候的过程中还可以做其它很多事,这种情况就是非阻塞。

在了解了同步与异步,阻塞与非阻塞的区别之后,接下来就是介绍开头介绍的四种I/O模型。

同步阻塞I/O

在这种模型中,当用户空间的应用程序执行一个系统调用,这时应用程序就会被阻塞直到系统调用结束(数据传输完成或者发生错误)。当被阻塞时,应用程序不会浪费cpu而只是简单的等待。

下图给出了传统的阻塞I/O模型,这也是目前应用程序中最为常用的一种模型。其行为非常容易理解,其用法对于典型的应用程序来说都非常有效。在调用 read 系统调用时,应用程序会阻塞并对内核进行上下文切换。然后会触发读操作,当响应返回时(从我们正在从中读取的设备中返回),数据就被移动到用户空间的缓冲区中。然后应用程序就会解除阻塞(read 调用返回)。

同步非阻塞I/O

 同步阻塞I/O的一种效率稍低的变种是同步非阻塞I/O。在这种模型中,设备是以非阻塞的形式打开的。这意味着I/O操作不会立即完成,read 操作可能会返回一个错误代码,说明这个命令不能立即满足(EAGAIN 或 EWOULDBLOCK),如下图所示。


非阻塞的实现是I/O命令可能并不会立即满足,需要应用程序调用许多次来等待操作完成。这可能效率不高,因为在很多情况下,当内核执行这个命令时,应用程序必须要进行忙碌等待,直到数据可用为止,或者试图执行其他工作。正如上图所示的一样,这个方法可以引入I/O操作的延时,因为数据在内核中变为可用到用户调用 read 返回数据之间存在一定的间隔,这会导致整体数据吞吐量的降低。

异步阻塞I/O

另外一个阻塞解决方案是带有通知的非阻塞I/O。在这种模型中,配置的是非阻塞I/O,然后使用阻塞 select 系统调用来确定一个I/O描述符何时有操作。使 select 调用非常有趣的是它可以用来为多个描述符提供通知,而不仅仅为一个描述符提供通知。对于每个描述符来说,我们可以请求这个描述符可以写数据、有读数据可用以及是否发生错误的通知。

select 调用的主要问题是它采用轮询的方式确定哪个描述符可用,所以效率不是非常高。尽管这是异步通知使用的一种方便模型,但是对于高性能的I/O操作来说不建议使用。

异步非阻塞I/O

最后,异步非阻塞I/O模型是一种处理与I/O重叠进行的模型。读请求会立即返回,说明 read 请求已经成功发起了。在后台完成读操作前,应用程序然后会执行其他处理操作。当 read 的响应到达时,就会产生一个信号或执行一个基于线程的回调函数来完成这次I/O处理过程

在一个进程中为了执行多个I/O请求而对计算操作和I/O处理进行重叠处理的能力利用了处理速度与I/O速度之间的差异。当一个或多个I/O请求挂起时,CPU 可以执行其他任务;或者更为常见的是,在发起其他I/O的同时对已经完成的I/O进行操作。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值