IO模型概念

IO模型

IO概念

​ 输入输出(IO)模型是计算机系统中的一个关键概念,它描述了如何执行文件读、写、网络通信和其他类型的输入输出操作,IO模型描述了这些数据传输的方式和机制,以及它们对系统性能的影响


IO模型的基本组成和调用过程

组成:IO模型通常由输入设备和输出设备以及处理这些设备的软件(如操作系统)组成。在这个系统中,输入设备负责数据的输入,输出设备负责数据的输出,而处理设备则负责数据的中转和管理。

调用的过程:应用程序需要执行IO操作时,会向操作系统发起调用请求。操作系统随后会执行两个主要步骤:

  1. 准备数据阶段:操作系统等待I/O设备准备好数据,并将这些数据加载到内核缓冲区。
  2. 拷贝数据阶段:操作系统将内核缓冲区的数据拷贝到用户进程缓冲区

IO模型分类

在这里插入图片描述

1.阻塞IO

  • 在内核将数据准备好之前,系统的调用会一直等待
  • 所有的套接字默认都是阻塞方式

在这里插入图片描述

2.非阻塞IO

  • 内核中的数据未准备好,系统调用人仍会直接返回,并且返回EWOULDBLOCK错误码
  • 非阻塞IO往往需要程序员循环的方式反复尝试读写文件描述符, 这个过程称为轮询. 这对CPU来说是较大的浪费, 一
    般只有特定场景下才使用

在这里插入图片描述

阻塞与非阻塞理解

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态

阻塞调用是指调用结果返回之前,当前线程会被挂起. 调用线程只有在得到结果之后才会返回.

非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程

阻塞/非阻塞代码实验

代码

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>

// 数据没就绪,系统是以出错的形式返回的(不是错误)
// 没有就绪和真正的错误是同样的方式标识,用errnoL来区分
void SetNonBlock(int fd)
{
  int f1 = fcntl(fd, F_GETFL);//fcntl设置阻塞的函数
  if (f1 < 0)
  {
    perror("fcntl");
    return;
  }
  fcntl(fd, F_SETFL, f1 | O_NONBLOCK);// '|'加参数
}


int main()
{
  SetNonBlock(0);// 非阻塞设置
  while (1)
  {

    char buffer[10];
    ssize_t ret = read(0, buffer, sizeof(buffer) - 1); // 期望读的长度
    if (ret > 0)
    {
      buffer[ret] = 0;
      write(1, buffer, strlen(buffer));//向屏幕输出buffer个字节
      printf("read success,ret:%d,errno:%d\n", ret, errno);
      sleep(1);
    }
    else
    {
      if (errno == EAGAIN || errno == EWOULDBLOCK)
      {
        printf("数据未就绪\n");
        sleep(2);
      }
    }
  }
}

结果

  • 默认情况下阻塞等待

在这里插入图片描述

  • 非阻塞设置

数据没就绪,系统是以出错的形式返回的(不是错误)

没有就绪和真正的错误是同样的方式标识,用errno来区分(EAGAIN==11)

vim /usr/include/asm-generic/errno-base.h

在这里插入图片描述
在这里插入图片描述


3.信号驱动IO

  • 内核将数据准备好的时候,使用SIGIO信号通知应用程序进行IO操作(告诉应用程序什么时候开始数据拷贝)

在这里插入图片描述


4.多路转接IO

  • IO多路转接能同时接受多个等待文件描述符的就绪状态

在这里插入图片描述


5.异步IO

  • 内核在拷贝完成数据时候,通知应用程序

在这里插入图片描述


同步通信和异步通信

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

**synchronous communication **

同步,就是在发出一个调用时,在没有得到结果之前,该调用就不返回. 但是一旦调用返回,就得到返回值了; 换句话说,就是由调用者主动等待这个调用的结果

asynchronous communication

调用在发出之后,这个调用就直接返回了,所以没有返回结果; 换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果; 而是在调用发出后, 被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用

和线程同步的区分

两个或多个线程,这个线程需要在某些位置上协调他们的工作次序而等待、传递信息所产生的制约关系. 尤其是在访问临界资源的时候

调用就直接返回了,所以没有返回结果; 换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果; 而是在调用发出后, 被调用者通过状态、通知来通知调用者,或通过回调函数处理这个调用

和线程同步的区分

两个或多个线程,这个线程需要在某些位置上协调他们的工作次序而等待、传递信息所产生的制约关系. 尤其是在访问临界资源的时候

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值