本文所指的I/O均是网络I/O。

一. POSIX对同步、异步I/O的定义

  我们先大致看看POSIX对同步、异步的定义,不用细究,重点看我标红的部分就行。

  • 同步I/O会导致请求进程阻塞,直到I/O操作完成;
  • 异步I/O不会导致请求进程阻塞。

二. 同步、异步,阻塞、非阻塞

  个人理解同步与否与阻塞与否只是看待问题的不同维度,不用过于追究同步和阻塞有什么区别、以及异步和非阻塞有什么区别。

  我用小明购买火车票的例子大致先讲述下同步、异步,阻塞、非阻塞这几种情况的组合。

  • 同步阻塞,小明去火车站买票。首先,他需要在某一个售票窗口排队,当轮到他买票时,他需要告诉售票员他需要一张去上海的火车票,然后售票员需要去系统查询是否还有余票,有的话再收款出票,最后再把票给小明。在火车票到手之前,小明都不能做其他的事情,这种情况我们可以理解为阻塞。
  • 同步非阻塞,小明委托黄牛帮忙买火车票,然后小明可以做其他事情,但是需要每隔10分钟就打电话去询问黄牛票是否买到。黄牛买到票后,打电话通知小明说票已经买到,小明再去黄牛那里取火车票。这里的非阻塞指的是黄牛在买票的过程中,小明是不用等待的,他可以做其他事情,只是需不时地去询问黄牛票是否买好。但是,在小明去黄牛那里取票的过程中,小明还是不能做其他事情。
  • 异步阻塞,基本上没有这个说法。
  • 异步非阻塞,小明委托黄牛帮忙买火车票,然后小明可以做其他事情,黄牛买好票后会自动把票送到小明的家里。在这整个过程中,小明都可以做他自己想做的事情,不会被阻塞。

三. Unix中的I/O模型

  OK,有了上面的基础过后,我们可以开始讲I/O模型了。

  在网络Socket的输入操作中,I/O大致可以分为两个阶段,这个两个阶段大家务必掌握:

    1. 数据从网络中抵达,然后数据被复制到系统内核的缓冲区;
    2. 系统内核将内核缓冲区中的数据复制到用户进程的缓冲区中。

  在Unix中有5种I/O模型,它们是:

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

  下面,我们逐一分析每种I/O模型。

1.阻塞式I/O

  阻塞式I/O,即Blocking I/O。用户发起一个recvfrom系统调用,内核会等待数据从网络中到达。一旦数据准备就绪,系统内核将把自己的缓冲区中的数据拷贝到用户进程的缓冲区。在系统内核等待数据、复制数据的过程中,用户进程是不能做其他任何事情的,只能等待内核完成上述一系列的操作。

2.非阻塞式I/O

  与阻塞式I/O不同,非阻塞式I/O中,用户进程在发起recvfrom系统调用后可以立即返回,但是用户进程需要不时地循环询问系统内核数据是否已经准备就绪,即轮询(polling)。轮询往往会消耗大量的CPU时间。

  下图中,用户进程发起recvfrom系统调用,由于系统内核中数据尚未就绪,内核会立即返回EWOULDBLOCK错误码,防止用户进程阻塞。如此往复,直到系统内核中数据准备就绪。在数据就绪前,用户进程是非阻塞的,这也就是为什么这种模型叫非阻塞式I/O的原因。数据就绪后,和阻塞式I/O一样,内核将数据拷贝至用户进程,在数据拷贝的过程中,用户进程是阻塞的。

3.多路复用I/O

  多路复用I/O的关键函数为select或者poll。我们以select函数为例,当我们调用该函数时,用户进程将阻塞,直到系统内核中的数据准备好。数据就绪后,系统会通知用户进程数据已经可读,然后用户进程会发起recvfrom系统调用,将数据从内核拷贝到用户进程,在数据拷贝期间,用户进程是阻塞的。

  使用多路复用的优势是我们可以等待多个描述符就绪,对应到Java NIO多路复用模型中就是我们可以使用一个线程监听多个Channel的请求。

4.信号驱动I/O

  信号驱动I/O模型主要是让内核在描述符就绪的时候发送SIGIO信号通知用户进程,据我的了解,这种I/O模式运用的并不多,这里就不多描述,直接看图吧。

5.异步I/O

  用户进程在调用异步I/O函数后会立即返回,并且会让内核在完成所有操作后通知用户进程。在内核进行I/O操作的期间,我们的用户进程不会阻塞。特别需要注意的是,和前面四中I/O模型不同,异步I/O模型在内核将数据拷贝到用户进程时,我们的用户进程不会阻塞。

四. I/O模型对比

  对比上述5中I/O模型我们可以发现,前面4种模型的区别主要在第一阶段,而第二阶段都是一样的,即将数据从内核拷贝到用户进程时都会阻塞。根据POSIX对同步、异步I/O的定义,可以得出前4种模型都属于同步I/O。而第5种I/O,即异步I/O,两个阶段的操作都是由系统内核来处理的,用户进程并没有介入。

Unix中的I/O模型的更多相关文章

  1. 2018.5.4 Unix的五种IO模型

    阻塞非阻塞和异步同步 同步和异步关注的是消息通信机制,关注两个对象之间的调用关系. 阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态,关注单一程序. Unix的五种IO模型 以下基于Li ...

  2. 一文读懂高性能网络编程中的I/O模型

    1.前言 随着互联网的发展,面对海量用户高并发业务,传统的阻塞式的服务端架构模式已经无能为力.本文(和下篇<高性能网络编程(六):一文读懂高性能网络编程中的线程模型>)旨在为大家提供有用的 ...

  3. 阿里、腾讯热门面试题:聊聊Unix与Java的IO模型?(含详细解析)

    众所周知 如果去百度.腾讯等一线大厂面试,一定会深入考候选人的基础技术功底,其中尤为关键和重视的就是IO相关的技术和知识. 而要搞明白IO相关的概念,首先就得弄清楚同步与异步,阻塞与非阻塞到底是什么意 ...

  4. 今天在Mac机器上使用了Flex Builder编辑了一个源代码文件,保存后使用vim命令去打开时发现系统自动在每一行的结尾添加了^M符号,其实^M在Linux/Unix中是非常常见的,也就是我们在Win中见过的/r回车符号。由于编辑软件的编码问题,某些IDE的编辑器在编辑完文件之后会自动加上这个^M符号。看起来对我们的源代码没有任何影响,其实并不然,当我们把源代码文件Check In到svn之类

    今天在Mac机器上使用了Flex Builder编辑了一个源代码文件,保存后使用vim命令去打开时发现系统自动在每一行的结尾添加了^M符号,其实^M在Linux/Unix中是非常常见的,也就是我们在W ...

  5. C# 中DataTable转成模型List

    C# 中DataTable转成模型List 引入using System.Reflection; 命名空间 使用注意实体类的属性名必须和DataTable的列名一致 使用: DBList<Sto ...

  6. 在linux/unix中查找大文件

    在linux/unix中查找大文件,如查找大于100M文件的位置路径,查找等于10M文件的位置路径等等,下面就介绍几个实现快速查找的命令: 1. 查找指定目录下所有大于100M的文件,命令为 find ...

  7. CSS3中的弹性流体盒模型技术详解

    先回顾一下CSS1 和 CSS2中都已经定义了哪些布局方面的属性,这样也会增加我们理解弹性布局.   其实我们现在有很多一部分人,你们刚刚接触CSS层叠样式表,或者接触有一段时间了,但是却没有很好的去 ...

  8. Elasticsearch中的相似度模型(原文:Similarity in Elasticsearch)

    原文链接:https://www.elastic.co/blog/found-similarity-in-elasticsearch 原文 By Konrad Beiske 翻译 By 高家宝 译者按 ...

  9. 三种方式实现观察者模式 及 Spring中的事件编程模型

    观察者模式可以说是众多设计模式中,最容易理解的设计模式之一了,观察者模式在Spring中也随处可见,面试的时候,面试官可能会问,嘿,你既然读过Spring源码,那你说说Spring中运用的设计模式吧, ...

随机推荐

  1. Angular5 宏观把控

    1.首先,Angular5相对于Angular4有了一些新的特性: (1)i18n国际化管道: (2)一个组件可以以多个名称导出: (3)使用httpClient: 相比于http,httpClien ...

  2. python爬虫错误总结

    这几天突然想到学习爬虫,于是就从python开始,python教程瞄了两眼,就去网上找别人写的爬虫(爬音乐网站的歌曲) 磕磕绊绊中渐渐地熟悉了python中常用的库和模块. 1.python 2.x( ...

  3. lambda隐藏函数的嵌套

    # 隐藏函数嵌套 f = (lambda a,b :a if a>b else b)(1000, 2000008) print((lambda a,g:a if a > g else g) ...

  4. 前端开发APP,从HBuilder开始~ 【转】

    内容简介 介绍目前前端人员开发app的几种方法,具体介绍hbuilder开发app,一扇赞新的大门~ 无所不能的js 最开始js仅仅局限于网页上一些效果,操作网页内容等, 但是nodejs把js带入了 ...

  5. android获取手机机型、厂商、deviceID基本信息

    /** * 系统工具类 */ public class SystemUtil { /** * 获取当前手机系统语言. * * @return 返回当前系统语言.例如:当前设置的是"中文-中国 ...

  6. pandas用法小结

    前言 个人感觉网上对pandas的总结感觉不够详尽细致,在这里我对pandas做个相对细致的小结吧,在数据分析与人工智能方面会有所涉及到的东西在这里都说说吧,也是对自己学习的一种小结! pandas用 ...

  7. github page 配置hexo 博客 的常见错误

    缘起 最近看到好多的公众号作者推荐大家搭建自己的博客,自己手痒也搭建了一个个人博客lumang,具体过程就是一开始上网搜索一番教程,按照教程开始搭建,由于是windows的环境,同时教程也有很多的老旧 ...

  8. Java开源生鲜电商平台-推荐系统模块的设计与架构(源码可下载)

    Java开源生鲜电商平台-推荐系统模块的设计与架构(源码可下载) 业务需求: 对于一个B2B的生鲜电商平台,对于买家而言,他需要更加快速的购买到自己的产品,跟自己的餐饮店不相关的东西,他是不关心的,而 ...

  9. js基础进阶--编的实用技巧(一)

    我的个人博客:http://www.xiaolongwu.cn 在平时的开发中,编码技巧很重要,会让你少写很多代码,起到事倍功半的效果. 下面总结几种简单的技巧,大家共同学习一下 1. 利用+.-./ ...

  10. PAT1039: Course List for Student

    1039. Course List for Student (25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Y ...