五种基本IO模型介绍

10 篇文章 0 订阅
5 篇文章 0 订阅

一、阻塞式IO

大家最开始接触网络编程时,基本都是接触的阻塞式IO,在一个基本的TCP服务器程序中,我们使用recv()函数来接收对端发送的数据,而在对端未发送数据时,我们的服务器是阻塞在recv()函数处的,如:

recv(connFd, buf, MAX_RECV_DATA, 0);

以上就是一个阻塞式IO的基本例子,而使用recv()函数即为一次系统调用,此时会从应用切换到内核中运行,一段时间后再切换回来。我们以图表的形式来描述阻塞式IO模型:
在这里插入图片描述

二、非阻塞式IO

在介绍了阻塞IO后,我们不免会对非阻塞IO有对应的思考,阻塞IO是指系统调用时,我们的应用进程会等待内核返回的结果,这一等可能就是海枯石烂了,因此,非阻塞IO就应运而生啦!
非阻塞IO的做法是将我们使用的套接字设置为非阻塞,如:

fcntl(connFd, F_SETFL, O_NONBLOCK);

这样设置就相当于跟内核说:“哥们你好好干,我会按时来问你的”。于是乎,在非阻塞的情况下,我们需要在一个循环中不断地查询内核是否准备好数据,如果没准备好,内核会返回给我们一个EWOULDBLOCK的错误,相比于阻塞式IO呆呆地等在原地啥也不干,非阻塞显然可以在循环中处理一些其他事情,当然,频繁的调用recv()函数即频繁的进行系统调用,这会耗费我们大量的CPU资源的。我们同样给出相应图表:
在这里插入图片描述

三、IO复用

非阻塞IO虽然不用一直等待那啥也干不了,但是需要一直去轮询内核,浪费我们的CPU资源,此时我们或许会想,为啥不让内核主动告诉我们数据已经准备好了呢,这个时候我们再去取数据不就方便多了吗?
没错,这正是IO复用的初衷,我们熟悉的select/poll/epoll就是为了实现这种想法,同时能够支持多个套接字的网络事件,而select/poll/epoll的区别相信大家都有所了解,主要是支持的套接字数量和内核通知的区别,这里不展开进行讲述了哈。
下面以select为主,给出IO复用的图表:
在这里插入图片描述
可能有同学会产生疑问,这IO复用和阻塞IO一比好像没啥优化啊,都是一直阻塞在系统调用,实则不然,使用select/poll/epoll能够检测成百上千个甚至数十万的套接字,为实现咱们高并发打下了基础,这就是IO复用的优势哈!

四、信号驱动式IO

IO复用存在的问题式:select函数阻塞调用,等待数据处理完,我们在使用recv()函数发起系统调用去取数据。而信号驱动IO相比于IO复用,先注册了信号处理函数,当内核准备好数据时,给用户进程发送约定好的信号,然后用户进程再使用recv()函数取数据,这样就使得数据从等待到准备完成的期间用户进程不被阻塞。
我们给出对应图表:
在这里插入图片描述

五、异步IO模型

经过上面四种IO模型的介绍,它们或多或少都有不足,用户进程都需要阻塞在某个地方来等待相应结果,那么有没有一种模型不需要用户进程来等待内核返回的结果呢?当然是有的,异步IO模型就支持我们的想法,我们使用aio_read()进行一次系统调用之后,不需要等待内核准备数据,用户进程可以继续干其他事情,内核处理好之后再发送aio_read()中指定的信号给用户进程中设置的信号处理函数进行处理即可。
对应的IO模型如下:
在这里插入图片描述

咱们的IO模型介绍就告一段落啦,文中图表借鉴的是《UNIX环境编程第3版》。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: Linux IO 模型是指 Linux 操作系统中的 IO 处理机制。它的目的是解决多个程序同时使用 IO 设备时的资源竞争问题,以及提供一种高效的 IO 处理方式。 Linux IO 模型主要分为三种:阻塞 IO、非阻塞 IOIO 多路复用。 阻塞 IO 指的是当程序进行 IO 操作时,会被挂起直到 IO 操作完成,这种方式简单易用,但是对于高并发环境不太适用。 非阻塞 IO 指的是程序进行 IO 操作时,如果无法立即完成,会立即返回一个错误码,程序可以通过循环不断地进行 IO 操作来实现轮询的效果。非阻塞 IO 可以提高程序的响应速度,但是会增加程序的复杂度。 IO 多路复用指的是程序可以同时监听多个 IO 设备,一旦有 IO 事件发生,就会立即执行相应的操作。IO 多路复用可以提高程序的效率,但是需要程序员手动编写代码来实现。 Linux IO 模型还有其他的实现方式,比如信号驱动 IO 和异步 IO 等。但是这些方式的使用比较复杂,一般不常用。 ### 回答2: Linux中的IO模型是指操作系统在处理输入输出的过程中所遵循的一种方式。它主要包括阻塞IO、非阻塞IO、多路复用IO和异步IO四种模型。 阻塞IO是最简单的IO模型,当一个IO操作发生时,应用程序会被阻塞,直到IO操作完成才能继续执行。这种模型的特点是简单直接,但是当有多个IO操作时会造成线程的阻塞,影响系统的性能。 非阻塞IO是在阻塞IO的基础上发展而来的,应用程序在发起一个IO操作后可以继续执行其他任务,不必等待IO操作的完成。但是需要通过轮询来不断地检查IO操作是否完成,效率相对较低。 多路复用IO使用select、poll、epoll等系统调用来监听多个IO事件,当某个IO事件就绪时,应用程序才会进行读写操作,避免了前两种模型的效率问题。多路复用IO模型适用于连接数较多时的场景,如服务器的网络通信。 异步IO是最高效的IO模型,应用程序发起一个IO操作后,立即可以执行其他任务,不需要等待IO操作的完成。当IO操作完成后,操作系统会通知应用程序进行后续处理。异步IO模型常用于高吞吐量、低延迟的应用,如高性能服务器和数据库等。 总之,Linux IO模型提供了多种不同的方式来处理输入输出,每种模型都有其适用的场景和特点。选择合适的IO模型可以提高系统的性能和效率。 ### 回答3: Linux IO模型是指操作系统中用于处理输入输出操作的一种方法或机制。在Linux中,常见的IO模型有阻塞IO、非阻塞IOIO多路复用和异步IO。 阻塞IO是最基本IO模型,当应用程序发起一个IO请求时,它将一直阻塞等待直到IO操作完成,期间无法做其他任务。虽然简单易用,但是对资源的利用不高。 非阻塞IO在发起一个IO请求后,不会阻塞等待IO操作完成,而是立即返回并继续做其他任务。应用程序需要不断地轮询IO操作状态,直到操作完成。由于需要不断轮询,对CPU的占用较高,但可以提高资源的利用率。 IO多路复用是通过一个线程同时监听多个IO事件,从而实现并发处理多个IO操作。在IO多路复用模型中,应用程序不需要进行轮询,而是通过调用select、poll或epoll等系统调用监听多个文件描述符的IO事件。这样可以在单个线程中处理多个IO操作,提高并发性能。 异步IO模型在发起一个IO请求后,应用程序不需要等待IO操作完成,而是继续做其他任务。当IO操作完成后,操作系统会通知应用程序。异步IO模型需要操作系统的支持,效率较高,但实现较为复杂。 通过选择合适的IO模型,可以根据不同的应用场景来提高IO操作的效率和性能。例如,对于需要同时处理大量连接的服务器应用,IO多路复用是一种常见的选择;而对于需要处理大量IO操作的高性能服务器,则可以考虑使用异步IO模型

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿杰的小鱼塘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值