首先,我们要了解IO模型先要知道在底层操作系统是通过哪些设备来实现数据的传输,其次要了解IO模型中哪些是发生阻塞调用操作,然后有了上述的基本认知之后,开始来了解IO模型是如何演进,最后通过IO模型的演进我们要辨别IO模型中的关键术语联系与区分,上述的思维导图囊括以下要分享的知识点!

数据传输交换媒介

Unix操作系统结构图

概要说明

  • 用户空间: 将上述用户级别或者是unix编程的应用程序的部分称为用户空间,我们可以通过启动进程来调用内核命令完成从硬件设备读取或写入等操作

  • 系统内核: 是直接与计算机硬件打交道的应用程序级别,在计算机相关的书籍中也称为操作系统,可以通过操作系统级别提供的一些组件来帮助用户进程与计算机硬件完成通信交互的操作,可以称为一个中转站

  • 硬件: 对于网络编程而言,与关联的硬件设备就是网络接口控制器等设备,通过网络接口控制器将字节流数据传输到互联网再根据IP地址等信息传输到其他计算机系统应用程序,实现多台计算机系统之间的通信

  • 文件描述符(File descriptor):在linux/unix系统中,文件进程存储着一份文件描述表(数组存储),数组存储file结构指针类型,文件进程通过数组索引来完成文件的操作,这里的数组索引也就是文件描述符,简称为fd

至此,通过上述的图解以及简要说明可知,用户进程无法直接操作硬件设备,必须通过向内核发起请求命令,然后由内核向硬件设备解析并执行相应的命令操作,于是跨计算机的进程网络数据传输需要将数据发送到系统内核再到网络接口控制器,通过网络接口控制器实现计算机之间的通信,如下图所示:

网络IO阻塞操作

IO读取操作核心步骤

  • 用户进程向系统内核发起数据读取操作请求,必须等待内核从硬件设备中获取数据直到数据报准备完成

  • 当内核从设备中准备好数据的时候,需要将数据报从内核复制到用户空间中

IO阻塞操作

  • recvfrom函数:属于IO操作的系统调用,这里区分系统内核和用户进程,调用函数的时候需要从用户进程的上下文空间切换到内核空间中运行,一段时间之后才能切换回来

  • select/poll函数: 允许进程指示内核等待多个事件中的任何一个发生,并只在有一个或者多个事件发生抑或是超过指定时间段便唤醒用户进程,告知当前事件是否就绪状态

IO操作的对比

  • recvfrom函数: 调用当前函数的时候,此时用户进程受阻于系统内核,这个时候其他进程发起请求调用的时候须等待系统内核完成工作之外才能处理其他的进程请求,也就是1:1模型

  • select/poll函数:调用当前函数的时候,此时用户进程受阻于当前select函数,不断轮询向内核select就绪状态的描述符或者是超过指定时间段被唤醒,由于select系统函数调用是携带描述符集合到内核,因此可以对N个描述符进行监听(姑且称描述符的就绪状态为事件可读状态,后面论述均以事件论述),即N:1模型,如下图:

IO模型演进

基于上述的数据传输以及IO阻塞操作可知,网络编程需要读取网络传输过来的数据需要先经过系统内核再到用户空间,期间需要系统内核等待数据准备完成以及数据复制到用户空间两个步骤,同时为了简化概念,将TCP的低套接字等信息隐藏不做说明,用简单且易于理解的UDP传输方式来演示Unix下的5种IO模型

阻塞式IO模型

  • 自应用进程发起recvfrom系统调用,在此期间一直处于被阻塞,因为这个时候需要等待内核获取数据报信息复制到用户空间中,除非被中断异常返回,否则将一直处于阻塞状态

  • 以下是时序图展示阻塞式IO

非阻塞式IO模型

  • 非阻塞式主要体现在用户进程发起recvfrom系统调用的时候,这个时候系统内核还没有接收到数据报,直接返回错误给用户进程,告诉用户进程“当前还没有数据报可达,晚点再来

  • 用户进程接收到信息,但是用户进程不知道什么时候数据报可达,于是就开始不断轮询(polling)向系统内核发起recvfrom的系统调用“询问数据来了没”,如果没有则继续返回错误

  • 用户进程轮询发起recvfrom系统调用直至数据报可达,这个时候需要等待系统内核复制数据报到用户进程的缓冲区,复制完成之后将返回成功提示

  • 以下时序图展示NIO的方式

IO复用模型

  • IO复用模型是使用select或者poll函数向系统内核发起调用,阻塞于这两个之一的系统函数调用,而不是真正阻塞于实际的IO操作(recvfrom调用才是实际阻塞IO操作的系统调用)

  • 阻塞于select函数的调用,等待系统内核准备数据并通知当前事件为可读状态

  • 当select接收到系统内核通知事件为可读状态时,就可以向系统内核发起recvfrom调用将数据复制到用户空间的缓冲区

  • IO复用模式时序图如下

信号驱动式IO模型

  • 先开启套接字的信号IO驱动功能,并通过一个内置安装信号处理函数的signaction系统调用,当发起调用之后将会直接返回

  • 其次,等待内核从网络中接收数据报之后,向用户进程发送当前数据可达的信号给到信号处理函数

  • 信号处理函数接收到信息就发起recvfrom系统调用等待内核复制数据报到用户空间的缓冲区

  • 接收到复制完成的返回成功提示之后,应用进程就可以开始从网络中读取数据

  • 上述是基于信号驱动式IO模型,当系统内核描述符就绪时将会发送SIGNO给到用户进程,这个时候再发起recvfrom的系统调用等待返回成功提示,流程如下:

异步IO模型

  • 由POSIX规范定义,告知系统内核启动某个操作,并让内核在整个操作包括数据等待以及数据复制过程的完成之后通知用户进程数据已经准备完成,可以进行读取数据

  • 与上述的信号IO模型区分在于通过异步方式直接通知我们何时IO操作完成,而信号IO是通知我们何时可以启动一个IO操作

  • 时序图如下

5种IO模型分析

  • 对于阻塞式IO模型,属于1:1模型,也就是系统内核只能处理一个请求,其他请求过来的时候必须等待当前请求处理完成才能进行,性能相当差,可以通过多线程变更为N:1模型,与非阻塞式IO类似,区分在于前者多线程,后者单线程

  • 对于驱动式信号IO模型,虽然是非阻塞式IO模型,但是基于内核通知回调的实现机制比较复杂(在信号函数异步处理IO与读取数据操作要保持先后顺序,个人认为信号函数正确设计是不处理业务的,即后续的数据读取等操作)

  • 而对于非阻塞式IO模型,相比阻塞式IO而言,而是通过不断轮询的方式发起recvfrom系统调用,由于存在内核与用户空间的切换,会损耗性能

  • 对于IO复用模型而言,阻塞于select函数的调用(本质上是基于文件描述符集合的遍历),向内核注册对应的事件并等待事件可读或者超时通知到select函数

  • 而对于AIO模型而言,是一种实现真正的非阻塞异步IO方式,但是在linux/unix系统支持此IO模型设计并不确定

  • 目前大多数Unix/Linux服务器都是基于IO复用模型进行优化改进,即对select/poll方法进行增强优化

IO关键术语

同步与异步的定义

  • 同步:发起一个fn的调用,需要等待调用结果返回,该调用结果要么是期望的结果要么是异常抛出的结果,可以说是原子性操作(要么成功要么失败返回)

  • 异步: 发起一个fn调用,无需等待结果就直接返回,只有当被调用者执行处理程序之后通过“唤醒”手段通知调用方获取结果(唤醒的方式有回调,事件通知等)

  • 小结: 同步和异步关注的是程序之间的通信

阻塞与非阻塞的定义

  • 阻塞: 类比线程阻塞来说明,在并发多线程争抢资源的竞态条件下,如果有一个线程已持有锁,那么当前线程将无法获取锁而被挂起,处于等待状态

  • 非阻塞: 一旦线程释放锁,其他线程将会进入就绪状态,具备争抢锁的资格

  • 小结: 阻塞与非阻塞更关注是程序等待结果的状态

  • 由此可知,同步异步与阻塞非阻塞之间不存在关联,关注的目标是不一样的

同步IO与异步IO(基于POSIX规范)

  • 同步IO: 表示应用进程发起真实的IO操作请求(recvfrom)导致进程一直处于等待状态,这时候进程被阻塞,直到IO操作完成返回成功提示

  • 异步IO: 表示应用进程发起真实的IO操作请求(recvfrom),这个时候系统内核向用户进程将直接返回一个错误信息,“相当于告诉进程还没有处理好,好了会通知你”

  • 阻塞IO: 主要是体现发起IO操作请求通知内核并且内核接收到到请求之后如果让进程等待,那么就是阻塞

  • 非阻塞IO: 发起IO操作请求的时候不论结果如何直接告诉进程“不用等待,晚点再来”,那就是非阻塞

IO模型对比

根据上述的同步与异步IO定义并结合上述的IO模型可知,只有异步IO模型符合POSIX规范的异步IO,其他IO模型都存在recvfrom系统调用被内核阻塞,属于同步IO操作,由此可总结如下:

  • 也就是说,要么称为同步IO和异步IO,要么称为上述的IO模型名称

  • 大部分操作系统都是基于同步IO的方式实现,对于支持异步IO模型的操作系统还不确定,在实际工作中接触到的IO模型,从严格意义上来说应该称为Blocking-IO(阻塞IO)和Non-Blocking-IO(非阻塞IO),而不是同步IO和异步IO

  • 小结: 同步与异步针对通信机制,阻塞与非阻塞针对程序调用等待结果的状态

Unix网络编程之IO模型相关推荐

  1. 后端服务器网络编程之 IO 模型

    基本概念   在编写服务器端网络程序时,我们最常见到阻塞.非阻塞.同步和异步这四个词.它们的解释分别如下: 阻塞: 阻塞调用是指调用返回之前,当前线程会被挂起,只有当调用得到结果后才返回. 非阻塞:与 ...

  2. 网络套接字编程之IO模型详解

    网络套接字编程之IO模型详解 本文主要参考自<UNIX网络编程>(第1卷)(套接口API第3版) Unix下可用的五种I/O模型有: 阻塞式I/O 非阻塞式I/O I/O复用(select ...

  3. python编辑程序模型_python并发编程之IO模型

    了解新知识之前需要知道的一些知识 同步(synchronous):一个进程在执行某个任务时,另外一个进程必须等待其执行完毕,才能继续执行 #所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调 ...

  4. 网络编程之IO多路复用

    目录 一. 同步与阻塞 1.1 同步阻塞 1.2 同步非阻塞 1.3 异步阻塞 1.4 异步非阻塞 1.5 I/O多路 二.多路复用的技术 2.1 UNIX I/O Models 2.1.1 bloc ...

  5. unix网络编程之UNIX Domain Socket IPC (sockaddr_un )

    socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket.虽然网络socket也可用于同一台主机的进程间通讯(通过loop ...

  6. unix网络编程之socket函数

    目录 作用 内容 参数 int family int type int protocol 返回值 int 说明 作用 为了执行网络I/O,一个进程必须做的第一件事情就是调用socket函数,指定需要的 ...

  7. 浅析网络编程之Socket模型

    Winsock 的I/O操作   两种I/O模式  阻塞模式:执行I/O操作完成前会一直进行等待,不会将控制权交给程序.套接字 默认为阻塞模式.可以通过多线程技术 进行处理.          非阻塞 ...

  8. Linux/UNIX网络编程之API

    一.服务器端API(被动socket) 1.socket()函数 #include <sys/types.h> #include <sys/socket.h>   int so ...

  9. 网络编程之socket

    网络编程之socket 看到本篇文章的题目是不是很疑惑,what is this?,不要着急,但是记住一说网络编程,你就想socket,socket是实现网络编程的工具,那么什么是socket,什么是 ...

最新文章

  1. BDTC 2017丨大数据在金融、交通、医疗、工业领域落地实践与应用
  2. dso_loader.cc:55] Could not load dynamic library ‘cudart64_100.dll‘
  3. scrapy的post登录:renren
  4. 互联网公司前端初级Javascript面试题
  5. JAVA程序员面试必知32个知识点
  6. Qt + Python + OpenCV图标替换工具 之 项目介绍(一)
  7. AttributeError: module ‘urllib‘ has no attribute ‘urlopen‘错误
  8. 仿链家地图找房_我在深圳的第一个家 是在有着6000套房的工业区里
  9. Maven实战读书笔记(3)
  10. (转)VmWare下安装CentOS6图文安装教程
  11. 剑指offer面试题52. 两个链表的第一个公共节点(双指针法)
  12. Nginx软件优化【转】
  13. 5. Zend_Log
  14. 蓝懿iOS培训日志5 正反向传值及学习心得
  15. BZOJ2281 [SDOI2011]黑白棋 【dp + 组合数】
  16. 异步IO实现和应用场景
  17. Ubuntu临时修改ip地址
  18. ubuntu 安装 网易云音乐
  19. 随机过程 Class 3 条件期望
  20. Flutter 学习之路 -- 异步任务

热门文章

  1. (*长期更新)软考网络工程师学习笔记——Section 12 Linux系统与文件管理命令
  2. android按钮防止重复点击事件,实例详解Android解决按钮重复点击问题
  3. comment desc显示表结构_营销模块数据库表解析(二)
  4. 抛弃一键恢复。教你用vista一键还原备份多系统。图文教程
  5. python中使用什么注释语句和运算_Python基础知识
  6. flex布局怎么设置子元素大小_Chrome72 嵌套 flex 布局修改,你的网站可能会发生布局错乱...
  7. js打印线程id_一文讲透“进程,线程和协程”
  8. ckks方案优化最好的_网站优化关键词怎么选?好的关键词长什么样?
  9. 晟数学院 oracle,Oracle 控制文件存储解析
  10. C#学员信息管理试题