上次写了一篇文章:Unix IO 模型学习。恰巧在这次周会的时候,@fp1203 (goldendoc成员之一) 正好在讲解poll和epoll的底层实现。中途正好讨论了网络IO的同步、异步、阻塞、非阻塞的概念,当时讲下来,大家的理解各不相同,各执己见。搜索了网络上的一些文章,观点也各不相同,甚至连wiki也将异步和非阻塞当成一个概念在解释。

虽然网络上充斥了大量关于同步、异步、阻塞、非阻塞的文章,但大都是抄来抄去,没有一个权威的说法。但我找到了这一篇文章,该文章引用了《UNIX网络编程 卷1》的介绍,这本书的作者是Richard Stevens。如果有Richard Stevens在这方面的定义或者结论,那么我想,这应该是比较有说服力的了。

关于《UNIX网络编程 卷1》这本书,我特意找了英文原版,也共享出来了:大家可以下载《UNIX网络编程 卷1》的英文原版?HM格式)。

我看了6.2这节内容,这节内容就是讲IO模型的。刚刚提到的那篇文章,几乎就是翻译这个6.2节的。应该说,这个6.2节,对同步和异步的讲解,算是很清楚的。

下面是我自己理解的重点。

IO模型

目前unix存在五种IO模型(这也和上一篇文章:Unix IO 模型 中提到的一致),分别是:

· 阻塞型 IO(blocking I/O)

· 非阻塞性IO(nonblocking I/O)

· IO多路复用(I/O multiplexing)

· 信号驱动IO(signal driven I/O)

· 异步IO(asynchronous I/O)

IO的两个阶段

· 等待数据准备好

· 将数据从内核缓冲区复制到用户进程缓冲区

同步,异步的区别

那么究竟什么是同步和异步的区别呢?请重点读一下原文6.2节中的信号驱动IO和异步IO中的比较。最后总结出来是:

· 同步IO,需要用户进程主动将存放在内核缓冲区中的数据拷贝到用户进程中。

· 异步IO,内核会自动将数据从内核缓冲区拷贝到用户缓冲区,然后再通知用户。

这样,同步和异步的概念就非常明显了。以上的五种IO模型,前面四种都是同步的,只有第五种IO模型才是异步的IO。

阻塞和非阻塞

那么阻塞和非阻塞呢?注意到以上五个模型。阻塞IO,非阻塞IO,只是上面的五个模型中的两个。阻塞,非阻塞,是针对单个进程而言的。

当对多路复用IO进行调用时,比如使用poll。需注意的是,poll是系统调用,当调用poll的时候,其实已经是陷入了内核,是内核线程在跑了。因此对于调用poll的用户进程来讲,此时是阻塞的。

因为poll的底层实现,是去扫描每个文件描述符(fd),而如果要对感兴趣的fd进行扫描,那么只能将每个描述符设置成非阻塞的形式(对于用户进程来讲,设置fd是阻塞还是非阻塞,可以使用系统调用fcntl),这样才有可能进行扫描。如果扫描当中,发现有可读(如果可读是用户感兴趣的)的fd,那么select就在用户进程层面就会返回,并且告知用户进程哪些fd是可读的。

这时候,用户进程仍然需要使用read的系统调用,将fd的数据,从内核缓冲区拷贝到用户进程缓冲区(这也是poll为同步IO的原因)。

那么此时的read是阻塞还是非阻塞呢?这就要看fd的状态了,如果fd被设置成了非阻塞,那么此时的read就是非阻塞的;如果fd被设置成了阻塞,那么此时的read就是阻塞的。

不过程序已经执行到了这时候,不管fd是阻塞还是非阻塞,都没有任何区别,因为之前的poll,就是知道有数据准备好了才返回的,也就是说内核缓冲区已经有了数据,此时进行read,是肯定能够将数据拷贝到用户进程缓冲区的。

但如果换种想法,如果poll是因为超时返回的,而我们又对一个fd(此fd是被poll轮询过的)进行read调用,那么此时是阻塞还是非阻塞,就非常有意义了,对吧!

结论

· 判断IO是同步还是异步,是看谁主动将数据拷贝到用户进程。

· select或者poll,epoll,是同步调用,进行此调用的用户进程也处于阻塞状态。

· javaScript或者nodejs中的读取网络(文件)数据,然后提供回调函数进行处理,是异步IO。

关于IO的同步,异步,阻塞,非阻塞的更多相关文章

  1. 【转载】高性能IO设计 & Java NIO & 同步/异步 阻塞/非阻塞 Reactor/Proactor

    开始准备看Java NIO的,这篇文章:http://xly1981.iteye.com/blog/1735862 里面提到了这篇文章 http://xmuzyq.iteye.com/blog/783 ...

  2. 高性能IO设计模式之阻塞/非阻塞,同步/异步解析

    提到高性能,我想大家都喜欢这个,今天我们就主要来弄明白在高性能的I/O设计中的几个关键概念,做任何事最重要的第一步就是要把概念弄的清晰无误不是么?在这里就是:阻塞,非阻塞,同步,异步. OK, 现在来 ...

  3. 操作系统介绍-操作系统历史,IO,进程的三态,同步异步阻塞非阻塞

    1.操作系统历史 2.进程,IO,同步异步阻塞非阻塞 操作系统历史: 手工操作: 1946年第一台计算机诞生--20世纪50年代中期,计算机工作还在采用手工操作方式.此时还没有操作系统的概念. 手工操 ...

  4. linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO(转载)

      IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file ...

  5. 理解同步,异步,阻塞,非阻塞,多路复用,事件驱动IO

    以下是IO的一个基本过程 先理解一下用户空间和内核空间,系统为了保护内核数据,会将寻址空间分为用户空间和内核空间,32位机器为例,高1G字节作为内核空间,低3G字节作为用户空间.当用户程序读取数据的时 ...

  6. (转)同步异步,阻塞非阻塞 和nginx的IO模型

    同步异步,阻塞非阻塞 和nginx的IO模型  原文:https://www.cnblogs.com/wxl-dede/p/5134636.html 同步与异步 同步和异步关注的是消息通信机制 (sy ...

  7. Java IO 学习(一)同步/异步/阻塞/非阻塞

    关于IO,同步/异步/阻塞/非阻塞,这几个关键词是经常听到的,譬如: “Java oio是阻塞的,nio是非阻塞的” “NodeJS的IO是异步的” 但是这些东西听多了就容易迷糊,比方说同步是否就是阻 ...

  8. python并发编程之IO模型 同步 异步 阻塞 非阻塞

    IO浅谈 首先 我们在谈及IO模型的时候,就必须要引入一个“操作系统”级别的调度者-系统内核(kernel),而阻塞非阻塞是跟进程/线程严密相关的,而进程/线程又是依赖于操作系统存在的,所以自然不能脱 ...

  9. 转:IO模型-- 同步和阻塞,异步和非阻塞的区别

    源地址 http://hi.baidu.com/deep_pro/item/db0c581af1c1f17e7b5f2534 这些词之间的区别难倒了很多人,还有什么同步阻塞, 同步非阻塞, 异步阻塞, ...

随机推荐

  1. [学习笔记] 在Eclips 中导出项目

    有时候需要将自己完成的项目分享给别人,可以按如下步骤操作: 选择要导出的内容,设置导出的文件名. 然后点击,Finish 即可. 然后到d:\tmp 会看到文件:Hibernat_demo_001.z ...

  2. Mybatis之自动生成

    使用Mybatis来自动生成我们的dao接口,mapper文件和实体类. 1.pom.xml依赖: <dependencies> <dependency> <groupI ...

  3. 数据库连接池——C3P0&Druid(快速入门)

    数据库连接池--C3P0&Druid (一) 数据库连接池 每一个事物都有其存在的意义,在初学jdbc的时候,我们建立数据库连接对象后,会对其进行释放,但是数据库连接的建立和关闭是非常消耗资源 ...

  4. 5个Linux性能命令

      使用几个命令就可以管理Linux系统的性能了,下面列出了5个最常用的Linux性能命令,包括top.vmstat.iostat.free和sar,它们有助于系统管理员快速解决性能问题. (1)to ...

  5. springboot+mybatis 用redis作二级缓存

    1.加入相关依赖包: <?xml version="1.0" encoding="UTF-8"?> <project xmlns=" ...

  6. 聊聊BIO、NIO与AIO的区别

    题目:说一下BIO/AIO/NIO 有什么区别?及异步模式的用途和意义? 1F 说一说I/O首先来说一下什么是I/O? 在计算机系统中I/O就是输入(Input)和输出(Output)的意思,针对不同 ...

  7. Python取整数

    1.向下取整: int()>>> a = 14.38>>> int(a)14 2.向上取整:ceil()使用ceil()方法时需要导入math模块,例如>&g ...

  8. Scala学习十四——模式匹配和样例类

    一.本章要点 match表达式是更好的switch,不会有意外调入下一个分支 如果没有模式能够匹配,会抛出MatchError,可以用case _模式避免 模式可以包含一个随意定义的条件,称做守卫 你 ...

  9. iot平台异构对接文档

    iot平台异构对接文档 准备工作 平台提供的XAgent开发指南.pdf demo程序xagent-ptp-demo 平台上添加产品得到产品id和key 部署时需要插件的基础程序<xlink-x ...

  10. git 报错fatal: not a git repository (or any of the parent directories): .git

    产生原因:一般是没有初始化git本地版本管理仓库,所以无法执行git命令 解决方法:操作之前执行以下命令行:  git init 初始化git,即可解决: