首先先看如下几个问题,或者说我们经常会遇到的问题。

阻塞是否等于同步?
非阻塞是否等于异步?
同步一定是阻塞的么?
异步一定是非阻塞的么?
要把这四个概念讲明白,先从一顿简餐说起。假设你要做一顿便饭:烧土豆;烧茄子和米饭。CPU代表你,如下事件代表操作:

A1、切土豆、A2、烧土豆

B1、切茄子、B2、烧茄子

C1、淘米、C2、煮饭;

情况1:你做完A1再做B1再做C1,即:切完土豆、切茄子最后淘米;

情况2:你干一会A1再干一会B1,再干一会C1,即:一会切土豆、一会切茄子、一会淘米,直到三者做完;

情况1相当于开一个线程按顺序做,情况2相当于开三个线程分别作A1、B1、C1;

对于你来说:情况1显然要比情况2好,因为减少了切换时间,也就是说减少了不必要的拿起土豆,放下土豆,拿起茄子放下茄子的时间,这个时间就是CPU线程切换时所带来的额外开销,想象一下你要做100个菜。你的时间将大量耗在拿起某个菜放下某个菜的过程中,而不是干正事切菜配菜上。

A1、B1、C1对你来说是纯体力活,要全程参与,相当于CPU的纯运算操作。此时开多个线程分别做,还不如开一个线程一个一个按顺序做。

情况真是如此么?

如果你能像周伯通那样双手互搏,左手削土豆,右手削茄子,那么你就是双核CPU。如果你还能把双脚利用起来,左脚切冬瓜,右脚淘米,那么你就是四核CPU。你的工作效率将会大幅提升,还能给自己加一个菜:烧冬瓜。

那么真的会有提升么?

假设你已打通任督二脉,练到了4核的境地,你也愉快的开启了4个线程,不幸的是4个线程都开在了左手上,那你的左手效率将大幅提升:削土豆、削茄子、切冬瓜和淘米,不停的在左手切换。但右手和双脚会闲的蛋疼。虽然你是个4核,但低调的像个单核,甚至还不如单核。因此你要尽可能的将这4个线程分配到不同的手脚上去干不同的事。

上述三个操作完成只是做一顿饭的前戏,你还要把他们烧熟。

此时你还要完成 A2(烧土豆)、B2(烧茄子)、C2煮饭。 相对于A1B1C1,这三个操作你不需要全程参与,大部分时间是交给煤气灶、电饭煲完成。你只需要把土豆扔锅里,加点水和调料等待煮熟即可(这里将就一下,不讲究口味,要啥自行车)。A2、B2、C2相当于IO操作,你参与的时间很少,大部分是等待结果。

情况3:你做完A2再做B2再做C2,即:烧完土豆、烧茄子、最后煮饭,此时你就在厨房啥事不干就是干等;

情况4:你做A2的同时,又开了一个煤气灶烧了茄子,同时又将米放入电饭煲中开煮,然后你去客厅看乡爱N部曲。

对你而言显然情况4要优于情况3,做一顿饭的时间将大幅缩短,你不用一直呆在厨房,你还有时间去看电视。情况3就是阻塞同步。

你真的能安心看好电视么?

显然不能,你要确保土豆、茄子是否烧熟或者是否烧糊,就要不停从客厅到厨房去查看一下,这就是非阻塞轮询。虽然比情况3好一点,但也好不到哪去,因为你要往返跑,还能让人愉快的看东北F4么?在你忙着从厨房到客厅,客厅到厨房的时候,电饭煲发出了“biu”的一声,此时你知道饭烧好了。

A2、B2的操作对你而言就是非阻塞轮询,虽然不阻塞了(在厨房傻等)可惜累成狗。C2操作对你而言就是异步,电饭煲把饭做好后通知你结果,这样你就无需像烧土豆、茄子那样跑断腿。

此时你的女朋友来了!!

你很激动,需要临时加几个菜。这时候你可以在等A2、B2、C2结果的同时,处理其它菜品,比如切西红柿、清洗小龙虾、做个狮子头、拌个凉菜,甚至出去买瓶酒。土豆烧好后,你就烧西红柿;米饭煮好后你就烧龙虾,烧龙虾时你又可以剁肉做狮子头。这样你可以一直烧下去,烧很多很多菜。

这时候你的利用率是最高的,几乎没有等待时间,因为你的女朋友来了你很开心,开心的想一直烧下去。。。。。。
这时候你必然会发挥自己的多核性能,把你四肢的主观能动性都调动起来,而且会调度的很均衡,让电视里的尼古拉斯赵四见鬼去吧。。。。。。
这时候你会发现自己已经从一个纯粹的CPU进化为一个懂业务的高性能服务器:高并发、高吞吐量和低延迟。你的女朋友对你的性能相当满意,并对你的这一系列骚操作起了一个名字:非阻塞异步!
因为有了IO操作才会有阻塞,才会出现同步和异步。因为有大量IO操作,才会有高并发的设计,如果只是纯CPU运算,不涉及到CPU对外围IO设备的读写,那么就不存在高并发设计。也就是说无论切土豆还是切茄子,都是纯体力工作,纯CPU运算工作。那么对CPU而言,开一个线程计算和开100个线程计算,只会徒增CPU切换时间,当然这种情况下也不存在所谓的阻塞、非阻塞、同步和异步。所谓的高性能就是如何在处理大量IO的情况下,让CPU去干更多的正事(切菜配菜烧菜),而不是去等待或者去看电视。

虽然你的女朋友对你很满意,但你并不能骄傲,你还有提升的空间,就是如何提升自己洗菜、配菜的速度,就业务而言就是如何设计高效的内存池、缓存、Hash表。。。。,这样你就可以在等待IO结果的同时,处理更多的业务了。

回到本文开头的四个问题

就CPU而言IO阻塞是绝对的,因为所有设备都不会快过CPU。只是有的设备快有的慢,有的稳定有的不稳定,比如磁盘IO相对于网络IO就比较快速和稳定。阻塞和非阻塞的意义在于内核在这种绝对阻塞上呈现给应用层的形式。换句话说,就是内核给应用层提供访问这些IO的函数是阻塞的还是非阻塞的,这两者的差别就导致了后面的同步和异步。

——————————————最后收尾总结一下————————————————

阻塞和非阻塞是指内核提供给应用层的IO访问函数是等待IO结果返回还是立即返回,等待结果的就是阻塞函数,立即返回的就是非阻塞函数,是针对函数而言;
同步和异步是指应用层在调用内核的阻塞函数或非阻塞函数后所才取的处理方式,是针对操作而言。
如果内核只提供阻塞IO函数,你的应用层操作必然是同步;
如果内核也提供了非阻塞IO函数,你的应用层操作可能是同步,也可能是异步;
如果内核没有提供IO完成通知机制,你的应用层也无法实现完全的异步。
这些函数和操作的组合就产生了不同的IO模型,或者说阻塞函数、非阻塞函数、同步操作、异步操作之间的组合就是IO模型。通常有四种组合:同步阻塞,同步非阻塞,异步阻塞,异步非阻塞

编写服务器时,我们大部分使用的是异步阻塞IO模型。就是既调用了阻塞函数,也调用了非阻塞函数。比如读写操作是非阻塞的,但select/wait却是阻塞的。这种模型在windows下衍生出了事件(Event)和重叠(Overlapped)模型。在linux下衍生出了poll和epoll模型。不同的IO模型适用于不同业务场景,需要根据你的具体业务而定。如果只是客户端程序,阻塞同步就很好,代码简洁清晰。

什么是阻塞、非阻塞、同步和异步以及IO模型的更多相关文章

  1. 异步|同步&阻塞|非阻塞

    异步|同步:区别在于发出一个功能调用时,是否马上得到返回结果 阻塞|非阻塞:区别在于调用结果返回之前,当前线程是否挂起 node.js:单线程.异步非阻塞模型 单线程与异步不矛盾,与并发是矛盾的 ht ...

  2. 阻塞非阻塞,同步异步四种I/O方式

    举一个去书店买书的例子吧: (同步)阻塞: 你去书店买书,到柜台告诉店员,需要买一本APUE,然后一直在柜台等.(阻塞) 店员拿到书以后交给你. (同步)非阻塞: 你去书店买书,到柜台告诉店员A,需要 ...

  3. 进程&线程 同步异步&阻塞非阻塞

    2015-08-19 15:23:38 周三 线程 线程安全 如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码 线程安全问题都是由全局变量及静态变量引起的 若每个线程中对 ...

  4. I/O阻塞非阻塞,同步异步

    http://www.cnblogs.com/luotianshuai/p/5098408.html "阻塞"与"非阻塞"与"同步"与&qu ...

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

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

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

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

  7. Python番外之 阻塞非阻塞,同步与异步,i/o模型

    1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步/异步主要针对C端: 同步:      所谓同步,就 ...

  8. 阻塞与非阻塞、同步与异步 I/O模型

    I/O模型 Linux 下的五种I/O模型 阻塞I/O(blocking I/O) 非阻塞I/O (nonblocking I/O) I/O复用(select 和poll) (I/O multiple ...

  9. JAVA 中BIO,NIO,AIO的理解以及 同步 异步 阻塞 非阻塞

    在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 序号 问题 1 什么是同步? 2 什么是异步? 3 什么是阻塞? 4 什么是非阻塞? 5 什么是同步阻塞? 6 什么是同步 ...

随机推荐

  1. 基于Xposed Hook实现的Android App的协议算法分析小工具-CryptoFucker

    本文博客地址:https://blog.csdn.net/QQ1084283172/article/details/80962121 在进行Android应用的网络协议分析的时候,不可避免涉及到网络传 ...

  2. CVE-2010-3974:Windows 传真封面编辑器 FxsCover.exe 双重释放漏洞调试分析

    0x01 堆空间申请后的双重释放 Windows FxsCover 程序存储封面编辑器的信息,封面编辑器是传真服务的一个组件,通过解析特定的传真封面文件(.cov)时,会调用类析构函数对同一内存中的栈 ...

  3. 全套Project版本安装教程及下载地址

    1:Project 2007 安装教程及下载地址 https://mp.weixin.qq.com/s/8iI7x1qjon0yAdo3bStjzw 2:Project 2010 安装教程及下载地址 ...

  4. 【js】Leetcode每日一题-子数组异或查询

    [js]Leetcode每日一题-子数组异或查询 [题目描述] 有一个正整数数组 arr,现给你一个对应的查询数组 queries,其中 queries[i] = [Li, Ri]. 对于每个查询 i ...

  5. python分析《三国演义》,谁才是这部书的绝对主角(包含统计指定角色的方法)

    前面分析统计了金庸名著<倚天屠龙记>中人物按照出现次数并排序 https://www.cnblogs.com/becks/p/11421214.html 然后使用pyecharts,统计B ...

  6. Taro使用多线程Worker相关问题解决

    JavaScript 语言采用的是单线程模型,HTML5标准中的Web Worker ,为 JavaScript 创造多线程环境.微信小程序也有相应的Worker,同样具备多线程运行的能力 主页面中创 ...

  7. Go - 开箱即用,WEB 界面一键安装,没有项目经验,可以拿这个练手

    安装界面 启动程序之后,会在浏览器中自动打开安装界面. 因为程序会使用到 Redis 和 MySQL,所以安装前请输入 Redis.MySQL 配置信息,点击初始化按钮,会将用到的数据表和默认数据进行 ...

  8. 通用PE u盘装Ghost Win7系统教程

    通用PE u盘装Ghost Win7系统教程 导读 通用pe工具箱是现在最老牌的的U盘装系统和维护电脑的专用工具之一,一键式制作.操作简单便捷,几乎100%支持所有U盘,不再为装机烦恼们,抓紧时间下载 ...

  9. Python socket 编程实验

    实验内容 1.编写一个基于UDP协议的客户机与服务器程序,实现相互通讯. 2.编写一个基于TCP协议的客户机与服务器程序,实现相互通讯. 3.捕获以上两种通讯的数据包,使用Wireshark进行分析, ...

  10. MySQL 查询操作

    目录 基本语法 查询常量 查看表达式 查询函数 查询指定字段 查询所有列 列别名 表别名 条件查询 条件查询运算符 逻辑查询运算符 排序与分页 排序查询(order by) 排序方式 limit 分组 ...