前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >深入理解--异步和非阻塞同步和阻塞异步和非阻塞

深入理解--异步和非阻塞同步和阻塞异步和非阻塞

作者头像
desperate633
发布于 2018-08-22 09:30:39
发布于 2018-08-22 09:30:39
1K0
举报
文章被收录于专栏:desperate633desperate633

异步和非阻塞的概念实际上已经出现了很长一段时间。但是异步真正开始流行起来,是因为AJAX技术逐渐成为主流的web开发技术。非阻塞的概念真正流行起来,是当java引入NIO,也可以称作非阻塞IO的API,开始走进主流的开发人员的视线,真正流行起来,也可以认为是node.js带来的。

同步 ,异步,阻塞,非阻塞这几个概念相互之间联系紧密,很难区分。很多程序员都不知道它们之间的具体的不同。本文就会详细讨论这个问题,希望能帮助读者更好的了解这几个概念

同步和阻塞

首先,我们先开始介绍与异步和非阻塞对立的两个概念:同步和阻塞

对于web开发者来说,理解同步的概念相对比较容易,因为HTTP协议就是一个同步的协议。web浏览器向服务器发送一个请求并且等待它的响应。收到响应之后,浏览器才可以继续向服务器发送下一个请求,并且等待响应,周而复始的重复这个过程。在发送下一个请求之前必须等待响应的到达才行,这就成为了HTTP协议的一个巨大的性能瓶颈,当然为了解决这个问题,后来就出现了异步的AJAX技术。

阻塞的概念相对也是比较容易理解的。我们通过Java中的InputStream类的read方法来介绍阻塞的概念,文档中是这样描述read方法的:

If no byte is available because the end of the stream has been reached, the value -1 is returned. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown. 意思就是,如果已经到了流的末尾没有可读取的数据,那么就会返回-1。这个方法会一直阻塞,直到有可读取的数据,或者已经读到了流的末尾,或者抛出一个异常。

这个方法的调用会一直阻塞,因为他会一直等待直到输入的数据可以用来读取。这通常会造成性能的瓶颈,因为这个方法会阻塞,导致无法继续执行随后的操作。

异步和非阻塞

异步和非阻塞就是同步和阻塞的相反面。在直觉上,可能会感觉这两个概念会有一些类似,因为他们都可以允许你们的线程在等待结果或者返回的时候不需要挂起整个线程。但是他们又有不同,因为异步调用通常需要包括一个回调机制或者事件机制,去主动通知调用方此时响应的结果已经可用了。而非阻塞调用往往会先返回一个任意的结果,然后调用者会不定时的反复去尝试获取返回的结果,直到结果已经可用了。这里的区别就是一个主动通知和被动去询问。举个例子,你去音乐店买周杰伦的专辑,但老板告诉你,现在没货,你就回去了,等到货到了,准备好了,老板会主动打电话通知你,专辑已经到啦,快来买吧,这就是异步机制,是主动通知的。而非阻塞则是,老板不会主动通知你,而是你自己隔个一两天就去这家店主动问问,专辑到了么,直到有一次你询问的时候,终于发现专辑到了。非阻塞的概念常常用于I/O中,而异步的概念则相对应用的比较广泛。

特别的,异步I/O,意味着I/O操作是独立于当前的那个线程的操作而进行的。可以理解为,另外新开启了一个线程去执行I/O操作,当I/O操作完成之后会主动直接将结果返回。这里说的更详细一点就是,我们知道底层数据准备好之后,还要从内核区域拷贝到线程的缓冲区,非阻塞操作在这种意义上来说,又是同步的,因为非阻塞不会将这个拷贝数据的过程完成,而是当数据准备好了,告诉线程,你可以执行系统调用,将内核区域的数据拷贝到线程的缓冲区了,当然这个过程是同步,而且由于是系统调用,所以这个拷贝的过程也是阻塞的。而异步操作则不是,系统会开启一个线程当数据准备好了,这个线程还会完成这个从内核区将数据拷贝到线程缓冲区的过程,当数据拷贝完成了,才通知调用者,这时候调用者就直接可以用了。

我们在看一个更详细的异步I/O的例子:

我们假设同步I/O意味着发出一个I/O命令,然后一直等待,直到I/O操作完成。也就是说,你发出一个read命令,然后这个线程接下来的执行操作会一直等待,直到已经读到了内容。异步I/O则是你发出一个I/O命令,然后这个I/O不会立即完成。你可以先去执行接下来的程序。异步会实现一个接口,允许IO操作不阻塞当前的线程,而且当操作完成之后,会主动通知你操作已经完成。

Non-blocking 在这里有一个很好的解释: this StackOverflow answer:

This term is mostly used with IO. What this means is that when you make a system call, it will return immediately with whatever result it has without putting your thread to sleep (with high probability). For example non-blocking read/write calls return with whatever they can do and expect caller to execute the call again. try_lock for example is non-blocking call. It will lock only if lock can be acquired. Usual semantics for systems calls is blocking. read will wait until it has some data and put calling thread to sleep. 非阻塞I/O意味着当你发起一个系统调用的时候,他会立即返回一个结果,而不是将你的线程睡眠。非阻塞的读写操作,会收到一个立即的返回值,然后请求者会反复去重试,不断的去尝试,直到可以开始读写操作了。类似于忙等的状态,不断的测试,但是线程没有被阻塞。try_lock就是一个非阻塞的调用,他会尝试去获取锁,直到锁可以获取。通常来说,系统调用会进入内核,一般都是阻塞的,所以read操作往往是阻塞的,会等待可用数据,并且将线程休眠。

现在,我们应该对于异步和非阻塞的概念已经有所了解了。下面我们就举个现实中的例子来加强理解:

例如,传统的sockets API中,一个非阻塞的socket,通常会立即返回一个"would block" 的错误信息,然后需要调用独立的函数select or poll 去轮询检查什么时候可以再次尝试去读取。 但是异步的sockets (windows的sockets支持异步操作),.Net框架中也有异步I/O模型。你调用一个方法开始某个操作,然后 框架会在这个操作完成的时候,回调通知你,操作完成了。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.07.28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Java|网络IO之同步、异步、阻塞、非阻塞
最近在看《大型分布式网站架构-设计与实践》这本书时,文中提到阻塞式IO,其实之前我在看一些书籍时也经常听到同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO这些词。 那么同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别呢? 一、网络IO操作过程 对于一个网络IO (这里我们以read举例),它会涉及到两个系统对象,一个是调用这个IO的过程process (or thread),另一个就是系统
黄小怪
2018/05/21
3K3
socket阻塞与非阻塞,同步与异步、I/O模型
在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式:
用户6280468
2022/03/21
3.1K0
socket阻塞与非阻塞,同步与异步、I/O模型
socket阻塞与非阻塞,同步与异步、I/O模型
在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式:
黄规速
2022/04/14
2.3K0
socket阻塞与非阻塞,同步与异步、I/O模型
IO - 同步,异步,阻塞,非阻塞
同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出的答案都可能不同,比如wiki,就认为asynchronous IO和non-blocking IO是一个东西。这其实是因为不同的人的知识背景不同,并且在讨论这个问题的时候上下文(context)也不相同。所以,为了更好的回答这个问题,我先限定一下本文的上下文。 本文讨论的背景是Linux环境下的network IO。 本文最重要的参考文献是Richard Stevens的“UNIX® Network Programming Volume 1, Third Edition: The Sockets Networking ”,6.2节“I/O Models ”,Stevens在这节中详细说明了各种IO的特点和区别,如果英文够好的话,推荐直接阅读。Stevens的文风是有名的深入浅出,所以不用担心看不懂。本文中的流程图也是截取自参考文献。
后端技术探索
2018/08/09
2.2K0
阻塞和非阻塞、同步和异步的讲解
我个人对于网络编程有着强烈的兴趣,最近打算开始看 muduo 的网络库,了解到其构建了基于 Reactor 的事件处理机制,本质涉及 I/O 多路复用的知识。为了后续的理解,首先搞清楚一个有无数讲解却又令人费解的概念:阻塞和非阻塞、同步和异步。
泽霖
2023/11/26
1960
socket阻塞与非阻塞,同步与异步I/O模型
作者:huangguisu 原文出处:http://blog.csdn.net/hguisu/article/details/7453390
bear_fish
2018/09/20
3.4K0
socket阻塞与非阻塞,同步与异步I/O模型
一种理解同步/异步,阻塞/非阻塞,Linux IO 模型,select /poll /epoll 的方法
吕力
2017/07/24
6.9K4
一种理解同步/异步,阻塞/非阻塞,Linux IO 模型,select /poll /epoll 的方法
30分钟了解同步,异步,阻塞,非阻塞
同步,异步,阻塞,非阻塞,在一些场景下,它们是同一个概念的不同名字;在另一些场景下,它们是不同的概念。
SOEZ
2018/07/21
1.9K0
30分钟了解同步,异步,阻塞,非阻塞
关于IO的同步,异步,阻塞,非阻塞
上次写了一篇文章:Unix IO 模型学习。恰巧在这次周会的时候,@fp1203 (goldendoc成员之一) 正好在讲解poll和epoll的底层实现。中途正好讨论了网络IO的同步、异步、阻塞、非阻塞的概念,当时讲下来,大家的理解各不相同,各执己见。搜索了网络上的一些文章,观点也各不相同,甚至连wiki也将异步和非阻塞当成一个概念在解释。 虽然网络上充斥了大量关于同步、异步、阻塞、非阻塞的文章,但大都是抄来抄去,没有一个权威的说法。但我找到了这一篇文章,该文章引用了《UNIX网络编程 卷1》的介绍,
小小科
2018/05/02
8050
聊聊同步与异步、阻塞与非阻塞、I/O模型
程序员:假如我们执行A,B两个IO操作的时候,如果必须等待A完成后才能执行B那么这个就是
咻一咻
2020/05/29
1.3K0
也谈应用程序级的同步、异步、阻塞、非阻塞
这几个经常出现的词汇很容易会引起大家的误解,第一次接触相关词汇是在课上,当时上操作系统的老师说得比较模糊(阻塞==同步,非阻塞==异步),当时觉得挺对 的,
chain
2018/08/02
1K0
怎样理解阻塞非阻塞与同步异步的区别?
一讲到网络编程的I/O模型,总会涉及到这几个概念。问了很多人,没几个能清晰地讲出他们之间的区别联系,甚至在网络上也有很多不同的观点,也不知是中国文字释义的博大精深,还是本来这几个概念就是绕人不倦。今天我也来给大家讲解一下我对这几个概念的理解。
从大数据到人工智能
2022/06/15
4250
Linux的五种IO模型?
关注:<font color='red'>被调用者 B 是否有消息通知(回调函数)机制 把 最终结果 返回给 A。</font>
斯武丶风晴
2019/12/25
9440
Linux的五种IO模型?
华为一面,送分题
鱼皮最新原创项目教程,欢迎学习 大家好,我是鱼皮。今天给大家分享一道华为面试题:五种 IO 模型是什么?题目解析如下: 所谓 I/O,就是 Input/Output,输入/输出,在操作系统中,输入输出操作其实并不简单 工作在用户态的应用程序想要读取磁盘中的具体文件内容,就需要经过 System Call(系统调用)陷入内核态 因此,在操作系统中,输入输出操作通常都会包括以下两个阶段: 准备数据:内核缓冲区准备数据,等待其准备好 数据拷贝:从内核缓冲区向用户缓冲区复制数据 以网络通信即 Socket 上的输入
程序员鱼皮
2023/02/27
3380
华为一面,送分题
同步,异步,阻塞,非阻塞,IO,协程,websocket
注意区别非阻塞,阻塞和异步。阻塞和非阻塞会等待调用结果的,异步根本就不会等待调用结果,所以异步根本就没有阻塞和非阻塞的概念。
zy010101
2021/12/07
7000
同步,异步,阻塞,非阻塞,IO,协程,websocket
理解Linux里面的IO模型
User space(用户空间)和 Kernel space(内核空间)。Linux里面这么设计的目的主要是为了安全,即使用户空间崩溃了,内核也不受影响。所以在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核态模式,通过系统调用访问硬件设备。
我是攻城师
2018/10/19
2.1K0
理解Linux里面的IO模型
同步/异步,阻塞/非阻塞
什么是同步和异步 同步和异步是针对应用程序和内核的交互而言的, 同步指的是用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪,而异步是指用户进程触发IO操作以后便开始做自己的事情,而当IO操作已经完成的时候会得到IO完成的通知。 什么是阻塞和非阻塞 阻塞和非阻塞是针对于进程在访问数据的时候,根据IO操作的就绪状态来采取的不同方式,阻塞方式下读取或者写入函数将一直等待,而非阻塞方式下,读取或者写入函数会立即返回一个状态值。 同步/异步与阻塞/非阻塞的区别 同步与异步:针对数据访问的方式,程序是主动去询
欠扁的小篮子
2018/04/11
3.2K0
详解 Java 中 4 种 I/O 模型
同步、异步、阻塞、非阻塞都是和I/O(输入输出)有关的概念,最简单的文件读取就是I/O操作。而在文件读取这件事儿上,可以有多种方式。
Java技术栈
2019/01/02
6810
阻塞、非阻塞、多路复用、同步、异步、BIO、NIO、AIO 一锅端
本文会涉及到阻塞、非阻塞、多路复用、同步、异步、BIO、NIO、AIO等几个知识点,知识点虽然不难但经常容易搞混,这次带领大家再回顾一遍。
码农编程进阶笔记
2021/07/20
3840
阻塞、非阻塞、多路复用、同步、异步、BIO、NIO、AIO 一锅端
阻塞式/非阻塞式与同步/异步的区别
默认情况下,所有的套接字socket连接都是阻塞式的,在和操作系统交互的过程之中。比如说一个读操作:
翎野君
2023/05/12
1890
阻塞式/非阻塞式与同步/异步的区别
相关推荐
Java|网络IO之同步、异步、阻塞、非阻塞
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文