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

阻塞是否等于同步?
非阻塞是否等于异步?
同步一定是阻塞的么?
异步一定是非阻塞的么?
要把这四个概念讲明白,先从一顿简餐说起。假设你要做一顿便饭:烧土豆;烧茄子和米饭。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. Android Apk加固的初步实现思路(dex整体加固)

    一.前 言 Android Apk加固的发展已经有一段时间了,相对来说本篇博客要记录的Android加壳的实现思路是4年的东西了,已经被老鸟玩烂了,Android加固的安全厂商也不会采用这么粗犷的方式 ...

  2. hdu4982 暴搜+剪枝(k个数和是n,k-1个数的和是平方数)

    题意:       给你两个数n,k问你是否怎在这样一个序列:      (1)这个序列有k个正整数,且不重复.      (2)这k个数的和是n.      (3)其中有k-1个数的和是一个平方数. ...

  3. 哈希爆破神器Hashcat的用法

    目录 HashCat HshCat的使用 使用Hashcat生成字典 使用Hashcat破解NTLMv2 HashCat HashCat系列软件在硬件上支持使用CPU.NVIDIA GPU.ATI G ...

  4. JavaScript 包管理器 -Yarn

    Fast, reliable, and secure dependency management. 官网地址 Github 特性 离线模式:如果您之前下载了软件包,则可以在没有任何互联网连接的情况下安 ...

  5. 【一】kubernetes学习笔记-Pod概念

    一.Pod 控制器类型 Pod概念 当一个 Pod 创建后,Pause 容器就会随着 Pod 启动,只要是有 Pod,Pause 容器就要被启动. 在同一个 Pod 里面的容器不能出现端口冲突,否则这 ...

  6. Linux上的Shebang符号(#!)

    使用Linux或者unix系统的同学可能都对#!这个符号并不陌生,但是你真的了解它吗? 本文了将给你简单介绍一下Shebang("#!")这个符号. 首先,这个符号(#!)的名称, ...

  7. OO第一单元总结-多项式求导

    OO第一单元总结-多项式求导 一.第一.第二次作业总结 因为前两次作业设计复杂度差别不大,因而放在这里统一总结. 基于度量分析程序结构: 前两次作业确实存在缺乏可拓展设计的构想,基本还是面向过程的思维 ...

  8. Mac OSX系统homebrew update Fetching failed问题解决方案

    1. brew update error (i) 问题出现及现象描述 昨天换了台电脑,有些软件需要重新安装或更新一下,遇到了下面的问题 cv@xys-MacBook-Pro ~ % brew upda ...

  9. 其他CSS属性

    一.设置元素的颜色和透明度 a.color color 属性规定文本的颜色.这个属性设置了一个元素的前景色(在 HTML 表现中,就是元素文本的颜色):光栅图像不受 color 影响.这个颜色还会应用 ...

  10. Win10屏幕亮度不能调节,调节无效怎么办?

    Win10屏幕亮度不能调节,调节无效怎么办? 听语音 浏览:1027 | 更新:2019-11-22 11:43 1 2 3 4 5 6 7 分步阅读 一些用户在使用win10系统之后,出现了电脑屏幕 ...