上海古都建筑设计集团,上海办公室装修设计公司,上海装修公司高质量的内容分享社区,上海装修公司我们不是内容生产者,我们只是上海办公室装修设计公司内容的搬运工平台

【Linux C | IO模型】UnixLinux系统的5种IO模型 | 图文详解

guduadmin513月前

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀

🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭

🤣本文内容🤣:🍭介绍 Unix / Linux系统的5种IO模型🍭

😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你——泰戈尔🍭

🕛发布时间🕛:2024-02-01 00:09:45

本文未经允许,不得转发!!!

目录

  • 🎄一、概述
    • ✨1.1 什么是 I/O
    • ✨1.2 五种 I/O 模型介绍
    • 🎄二、阻塞I/O模型
    • 🎄三、非阻塞I/O模型
    • 🎄四、复用式I/O模型
    • 🎄五、信号驱动式I/O模型
    • 🎄六、异步I/O模型

      【Linux C | IO模型】UnixLinux系统的5种IO模型 | 图文详解,在这里插入图片描述,第1张

      🎄一、概述

      ✨1.1 什么是 I/O

      I/O 是 Input/Output 的缩写,意思是输入输出,一般指操作系统与硬件设备(磁盘、网卡)的数据写入或读取。常见的IO有以下两种:

      • 磁盘I/O:与磁盘的数据交互,读取磁盘数据 或 写入数据到磁盘;在Linux编程中,可以使用open、read、write等函数来操作文件描述符实现与磁盘的数据交互。
      • 网络I/O:通过网卡与其他主机或本机其他进程的数据交互;在Linux编程中,可以使用socket、read、write等函数来操作套接字描述符实现网络I/O。

        ✨1.2 五种 I/O 模型介绍

        在了解 I/O 模型之前,先看看操作系统是怎样与磁盘或网卡交换数据(操作I/O)的,一般分为两个步骤,下面以数据输入为例:

        • 1、等待数据到达网卡(或数据已存在与磁盘),将数据复制到内核的某个缓冲区;
        • 2、再将数据复制到应用层的进程的缓冲区。

          之所以这样要分成这两个步骤去操作IO,是因为操作系统是分层的,有内核空间 和 用户空间,操作硬件设备都需要通过内核去操作,用户空间一般不直接操作硬件。

          【Linux C | IO模型】UnixLinux系统的5种IO模型 | 图文详解,在这里插入图片描述,第2张

          正是因为,数据从硬件设备到应用层缓冲区需要经过内核,所以存在一个等待的过程,这个过程被称为阻塞。由于这个阻塞的情况,再加上内核一些避免阻塞的机制,使 Unix / Linux 系统有5种 I/O 模型:

          • 阻塞I/O模型:一直等待数据到应用层缓冲区;
          • 非阻塞I/O模型:不等待数据完成,如果数据没到应用层就返回错误;
          • 复用式I/O模型:不等待数据完成,让其他系统调用帮忙等着;
          • 信号驱动式I/O模型:不等待数据完成,让内核准备好数据后就通知进程;
          • 异步I/O模型:告诉内核要读取哪些数据,让内读取完数据后再通知进程。

            【Linux C | IO模型】UnixLinux系统的5种IO模型 | 图文详解,在这里插入图片描述,第3张


            【Linux C | IO模型】UnixLinux系统的5种IO模型 | 图文详解,在这里插入图片描述,第4张

            🎄二、阻塞I/O模型

            阻塞I/O模型是使用得最多的IO模型,默认情况下,大部分IO操作都是阻塞的。

            阻塞是指调用该系统调用后,需要等待内核获取完数据,再把数据复制到应用层缓冲区后,该系统调用才回返回。

            如下图:应用层的进程调用recvfrom后,告诉内核要读取某个套接字的数据,内核就开始等待数据,等到数据准备好了,再将数据复制到应用层的用户空间,复制完成后,recvfrom函数读取到数据并返回。

            【Linux C | IO模型】UnixLinux系统的5种IO模型 | 图文详解,在这里插入图片描述,第5张

            阻塞I/O模型,就像你要去买奶茶,但前面很多人在买,你的奶茶没做好,你就一直在奶茶店等着你的奶茶,直到做好拿走。


            【Linux C | IO模型】UnixLinux系统的5种IO模型 | 图文详解,在这里插入图片描述,第6张

            🎄三、非阻塞I/O模型

            进程把一个描述符fd设置成非阻塞是在通知内核:当所请求的I/O操作非得把本进程投入睡眠,才能完成时,不要把本进程投入睡眠,而是返回一个错误(EWOULDBLOCK)。EWOULDBLOCK这个单词由would block组成,表示告诉进程会阻塞。

            看下图,应用层的进程调用recvfrom获取数据时,因为内核准备好的数据,直接返回EWOULDBLOCK,紧接着,进程又调用recvfrom获取数据,内核仍没有准备好的数据,返回EWOULDBLOCK,前面三次都没有数据,知道第四次调用recvfrom获取数据时,内核的数据准备好了,将数据复制到用户空间,返回给应用的调用进程。

            轮询:当一个进程对一个非阻塞的描述符循环调用recvfrom,称为轮询。应用程序持续轮询内核,会消耗大量的CPU时间,所以这样轮询访问数据的模型比较少用。轮询访问就类似下面伪代码。

            while(1)
            {
            	recvfrom(...);
            	usleep(1000);
            }
            

            【Linux C | IO模型】UnixLinux系统的5种IO模型 | 图文详解,在这里插入图片描述,第7张

            非阻塞I/O模型,就像你要去买奶茶,但前面很多人在买,你来拿奶茶时,奶茶店没做好,你就马上走了,过一会又来拿,又没做好,你又走了,过一会又来拿。。。这样循环来查看奶茶做好了没,直到某一次,奶茶做好了,你就拿走。


            【Linux C | IO模型】UnixLinux系统的5种IO模型 | 图文详解,在这里插入图片描述,第8张

            🎄四、复用式I/O模型

            I/O复用(I/O multiplexing),可以让我们阻塞在其他系统调用函数上,而不是阻塞在真正的I/O系统调用上。但是阻塞在其他系统调用函数也还是阻塞啊,有什么区别吗?区别在于,如果需要对多个(大于1个)描述符进行IO操作时,select或poll系统调用可以同时监控多个描述符是否可读、可写,而阻塞IO只要阻塞在那就干不了其他事情了。

            下图使用select函数演示复用I/O模型,应用层进程调用select系统调用,并将感兴趣的描述符通知内核,内核等待数据到达,发现select函数感兴趣的描述符的数据准备好了,就马上让select返回该描述符可读,然后进程再调用recvfrom函数来获取数据,因为此时数据已准备好,所以内核直接将数据复制到用户空间,返回给recvfrom的调用进程。

            【Linux C | IO模型】UnixLinux系统的5种IO模型 | 图文详解,在这里插入图片描述,第9张

            复用式I/O模型,就像你要去买奶茶,但前面很多人在买,你就花钱找了个黄牛,帮你在那里等,奶茶做好之后,黄牛就打电话让你来拿。


            【Linux C | IO模型】UnixLinux系统的5种IO模型 | 图文详解,在这里插入图片描述,第10张

            🎄五、信号驱动式I/O模型

            信号驱动式I/O模型,让内核在描述符的数据准备好的时候发SIGIO信号给进程,进程再调用recvfrom函数来获取数据。

            信号驱动式IO是指进程预先告知内核,使得当某个描述符上发生某事时,内核使用信号通知相关进程。

            针对一个套接字使用信号驱动式IO (SIGIO)要求进程执行以下3个步骤。

            (1)建立SIGIO信号的信号处理函数。

            (2)设置该套接字的属主,通常使用fcntl的F_SETOWN命令设置。

            (3)开启该套接字的信号驱动式IO,通常通过使用fcnt1的F_SETFL命令打开O_ASYNC标志完成。

            下图:先建立了SIGIO信号处理函数并设置其他配置,然后使用sigaction注册SIGIO的处理函数到内核,内核数据准备好了就会给该进程发送SIGIO信号,进程接收SIGIO信号后,进入SIGIO的信号处理函数,然后会调用recvfrom函数,此时数据已准备好,所以内核直接将数据复制到用户空间,返回给recvfrom的调用进程。

            【Linux C | IO模型】UnixLinux系统的5种IO模型 | 图文详解,在这里插入图片描述,第11张信号驱动式I/O模型,就像你要去买奶茶,但前面很多人在买,你不想等,于是,你把手机号码给到奶茶店,等奶茶做好了,店主给你打电话,你再去拿奶茶。


            【Linux C | IO模型】UnixLinux系统的5种IO模型 | 图文详解,在这里插入图片描述,第12张

            🎄六、异步I/O模型

            异步I/O(asynchronous I/O)的工作机制是:告知内核启动某个I/O操作,并让内核在整个操作(包括将数据从内核复制到我们自己的缓冲区)完成后通知我们。这种模型与信号驱动式I/O模型的主要区别在于:信号驱动式IO是由内核通知我数据准备好了,可以读取了;而异步I/O通知到进程时,数据已经读取完了。

            【Linux C | IO模型】UnixLinux系统的5种IO模型 | 图文详解,在这里插入图片描述,第13张

            异步I/O模型,就像你要去买奶茶,但前面很多人在买,你不想等,就干脆点外卖,等奶茶做好了,直接送到你手里,不需要你再去店里拿了。


            【Linux C | IO模型】UnixLinux系统的5种IO模型 | 图文详解,在这里插入图片描述,第14张

            如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁

            参考资料:

            《Unix网络编程卷1》

            https://blog.csdn.net/qq_54015483/article/details/131013426

            https://blog.csdn.net/qq_54015483/article/details/130943574

            https://blog.csdn.net/Bb15070047748/article/details/124699009

网友评论

搜索
最新文章
热门文章
热门标签
 
 梦见蛇咬自己是什么意思  没怀孕梦到胎动很厉害  梦见小孩子