当前位置: 代码网 > 服务器>服务器>Linux > 【linux高级IO(一)】理解五种IO模型

【linux高级IO(一)】理解五种IO模型

2024年07月31日 Linux 我要评论
本篇文章讲解了五种常见的IO模型: 阻塞IO,非阻塞IO,信号驱动IO, 多路转接, 异步IO.

在这里插入图片描述

1. 前言

本篇文章开始, 将与大家分享高级io相关的内容
本章重点:


2. 重谈对io的理解

io: input or output --> 访问外设 效率低
io一定是非常低效的, 以读取为例:

所以说, io = 等待 + 拷贝 !!!

记住这句话, 会一直贯穿整个io系列文章

探讨低效io和高效io:

很明显, io = 等待 + 拷贝.
所以可以得出下面的结论:

  • 低效io: 单位时间内, 大部分时间, io类接口都在等待
  • 高效io: 让等待的比重降低

接下来的五种io模型, 就是围绕着是否高效进行的


3. 阻塞io讲解

在这里插入图片描述

通俗来讲, 阻塞io就是, 你去河边钓鱼, 只拿一根鱼竿等于上钩, 并且时刻盯着水面


4. 非阻塞io讲解

在这里插入图片描述

非阻塞io往往需要程序员循环的方式反复尝试读写文件描述符, 这个过程称为轮询. 这对cpu来说是较大的浪费, 一般只有特定场景下才使用. 下面是非阻塞io的简单示例:

#include <fcntl.h>
#include <unistd.h>
#include<errno.h>
#include <cstdlib>
#include <iostream>
using namespace std;

//对指定的fd设置非阻塞
void setnonblock(int fd) {
    int fl = fcntl(fd, f_getfl);
    if (fl < 0) {
        cerr << "fcntl error" << endl;
        exit(1);
    }
    fcntl(fd, f_setfl, fl | o_nonblock);
}

int main() {
    setnonblock(0);
    while (1) {
        char buffer[1024];
        ssize_t s = read(0, buffer, sizeof(buffer) - 1);
        if (s > 0) {
            buffer[s] = 0;
            cout << buffer << endl;
        } else if (s == 0) {
            cout << "读到文件结尾了" << endl;
            break;
        }
        else
        {
            //1. 数据没用准备好 2. 真的出错了. 都以-1的返回值返回
            // 数据没有准备好,不算出错. 需要区分这两种情况
            if(errno == ewouldblock || errno == eagain)
            {
                cout<<"os底层数据还没就绪"<<endl;
                cout<<errno<<endl;
            }
            //被信号中断, 也不算read出错
            else if(errno == eintr)
            {
                cout<<"io interrupted by signal"<<endl;
            }
            else
            {
                cout<<"read error"<<endl;
                break;
            }
        }
        sleep(1);
    }
}

调用fcntl函数将fd设置为非阻塞

通俗来讲, 非阻塞io就是, 你去河边钓鱼, 也只用一根鱼竿, 但是你过一分钟才去看看有没有鱼上钩, 其他时间你可能在刷抖音


5. 信号驱动io

在这里插入图片描述

通俗来讲, 信号驱动io就是, 你去河边钓鱼, 也只拿一个鱼竿, 只不过鱼竿上有压力传感器, 一旦有鱼上钩就会发出声音提醒你. 其余时间我们当然可以愉快的刷抖音


6. io多路转接

在这里插入图片描述

通俗来说就是你拿一百个鱼竿去钓鱼, 同时等待一百种可能, 一旦有鱼上钩了, 会同时把所有上钩的鱼都拉上来, 这效率简直是指数级增长, 所以这也是在实际生活中使用的最多的io方案


7. 异步io

在这里插入图片描述

还是拿钓鱼的例子来说, 前面的钓鱼者, 不管你一次性带多少鱼竿(多路转接), 不管你在鱼竿上安装什么高科技(信号驱动), 但是你总得去河边, 自己拿着鱼竿钓鱼. 而异步io是怎么做的呢? 他直接雇佣了一个人帮它去钓鱼, 什么时候鱼上钩, 你等待了多久我都不在乎, 我只需要你在晚上九点的时候将钓的鱼全部带给我即可.


8. 理解异步和同步

同步和异步关注的是消息通信机制.

在这里插入图片描述

同步和异步在实际场景中怎样运用?

综上所述, 实际场景中要根据自己的情况和需求来觉得使用同步还是异步, 不要觉得在学习时都用同步, 以后工作了也就无脑的用同步


9. 总结以及拓展

本篇文章只是简单的介绍了io模型的几个分类, 其中, 最重要的模型是多路转接, 后面的文章会着重讲解它. 多路转接为什么重要? 因为它是业内最常用的用来提高并发性的模型, 后续大家都接触都reactor模型, 而reactor模型可以有多种实现方式, 而效率最高的reactor模型则是用多路转接实现的!!!


🔎 下期预告:多路转接之select 🔍
(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com