前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >I/O复用——几种I/O模型对比

I/O复用——几种I/O模型对比

原创
作者头像
jackieluo
修改2018-12-02 13:22:18
1.4K0
修改2018-12-02 13:22:18
举报
文章被收录于专栏:Jackie技术随笔Jackie技术随笔

I/O复用——几种I/O模型对比

之前在服务器进程终止中讨论的情形,TCP客户端同时要处理两个输入,一是标准输入,二是TCP套接口。而此时若是服务器进程被杀死,服务器尽管正确地给客户发送了FIN分节,但是由于此时客户正阻塞于标准输入fgets(),直到读完一行用户输入(也许此时TCP服务器已经死透了),才能看到那个文件结束符。

I/O复用

因此,我们需要一个能力,对于上面两个I/O,只要有一个或多个I/O条件满足,都应该正确地通知到,这个能力被称为I/O复用,由函数selectpoll支持。

I/O复用的典型应用场景

针对网络应用场景,有以下情形,

  1. 上面讨论过的客户同时处理多个描述字时(一般是交互式输入和网络套接口),此时必须使用I/O复用。
  2. 一个TCP客户同时处理多个套接口。
  3. 一个TCP服务器同时处理监听套接口和已连接套接口。
  4. 一个服务器同时处理TCP和UDP。
  5. 一个服务器同时处理多个服务或者多个协议。

I/O复用并非只限于网络编程,许多其他应用也大范围使用这个能力。

I/O模型概述

首先来看一下Unix下我们可用的五个I/O模型:

  1. 阻塞I/O
  2. 非阻塞I/O
  3. I/O复用
  4. 信号驱动I/O(SIGIO
  5. 异步I/O

一个输入操作一般有两个不同的阶段:

  1. 等待数据准备好。
  2. 从内核到进程拷贝数据。

对于套接口上的输入操作,上述步骤具体是:

  1. 等待数据到达网络,分组到达时,拷贝其到内核缓冲区。
  2. 将数据从内核缓冲区拷贝至应用缓冲区。

阻塞I/O模型

缺省时,所有套接口都是阻塞的。《Unix网络编程》一书中,前五章的所有例子都使用阻塞I/O模型。

为了阐述简单,这里以UDP套接口作为例子,将函数recvfrom视为系统调用,它会有从应用进程中运行和内核中运行的相互切换。

阻塞I/O模型
阻塞I/O模型

进程调用recvfrom,此系统调用直到数据报到达且拷贝到应用缓冲区或是出错才返回。此过程可能出现的错误是系统调用被信号中断。我们说的进程阻塞,指的是从进程调用recvfrom开始到它返回的这段时间,当进程返回成功提示时,应用进程开始处理数据报。

非阻塞I/O模型

如果一个套接口被设置成非阻塞模式时,上面说的数据报没有准备好时,进程不会睡眠,而是由内核返回一个错误。

仍讨论之前说的UDP数据报例子:

  1. 数据报没有准备好的时候,调用函数recvfrom,内核立即返回一个EWOULDBLOCK错误。
  2. 数据报准备好的时候,调用函数recvfrom,数据报从内核拷贝到应用缓冲区,recvfrom返回成功提示,进程紧接着会处理数据。

轮询

当一个应用进程对一个非阻塞描述字巡回调用recvfrom时,我们称此过程为轮询(polling)。应用进程连续不断地查询内核,数据是否准备好,这对CPU时间是极大的浪费。

非阻塞I/O模型
非阻塞I/O模型

I/O复用模型

在I/O复用模型下,我们不再阻塞于真正的I/O系统调用recvfrom,而是在selectpoll这两个系统调用之一阻塞。

例如,阻塞于select调用,等待数据报套接口(可以是多个中任意一个)可读,函数返回对应标识,此时便可调用recvfrom将数据报拷贝到应用缓冲区中。

I/O复用模型
I/O复用模型

尽管多了一次系统调用,但是select函数可以等待多个套接口描述字这一点,是使用I/O复用模型的一大理由。

信号驱动I/O模型

之前讨论过,内核可以产生信号,进程可以调用sigaction安装一个信号处理函数。这个模型的思路是,数据报准备号以后发送一个信号给进程,信号处理函数收到信号后,调用recvfrom,进行后续的拷贝和处理。

这一模型的好处是,任意一个系统调用都是非阻塞的,主循环可以继续进行,直到数据报准备好的信号到达。

信号驱动I/O模型
信号驱动I/O模型

异步I/O模型

异步I/O模型中,不再调用函数recvfrom,而是调用函数aio_read,给内核传递描述字,缓冲区指针,缓冲区大小,文件偏移,并告诉内核当整个操作完成时如何通知。此调用立即返回,进程不必阻塞等待I/O操作完成。

这里内核在操作完成时也会产生一个信号,与信号驱动I/O模型不同,这个信号要在数据由内核拷贝到应用缓冲区才产生。

异步I/O模型
异步I/O模型

五种I/O模型的比较

除了真正的异步I/O模型以外,其他几种模型,最后一阶段的处理都是相同的——阻塞于recvfrom调用,将数据从内核拷贝到应用缓冲区。

五个I/O模型的比较
五个I/O模型的比较

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • I/O复用——几种I/O模型对比
    • I/O复用
      • I/O复用的典型应用场景
    • I/O模型概述
      • 阻塞I/O模型
        • 非阻塞I/O模型
          • 轮询
        • I/O复用模型
          • 信号驱动I/O模型
            • 异步I/O模型
              • 五种I/O模型的比较
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档