`
vanadiumlin
  • 浏览: 504868 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

同步与异步IO、阻塞与非阻塞IO

 
阅读更多


同步与异步IO、阻塞与非阻塞IO (2010-04-28 10:42)分类: Linux_kernel


同步与异步IO、阻塞与非阻塞IO

很多时候我们常常看到同步与异步,阻塞与非阻塞的出现。有的地方直接将同步与阻塞画上了等号。异步与非阻塞画上了等号。事实上这是不对的。同步不等于阻塞,而异步也不等于非阻塞。下面就来仔细的看看同步与异步、阻塞与非阻塞的概念差别,及他们的组合应用。
同步:所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。按照这个定义,其实绝大多数函数都是同步调用(例如sin, isdigit等)。但是一般而言,我们在说同步、异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务。最常见的例子就是SendMessage。该函数发送一个消息给某个窗口,在对方处理完消息之前,这个函数不返回。当对方处理完毕以后,该函数才把消息处理函数所返回的 LRESULT值返回给调用者
异步:异步的概念和同步相对。当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。以 CAsycSocket类为例(注意,CSocket从CAsyncSocket派生,但是起功能已经由异步转化为同步),当一个客户端通过调用Connect函数发出一个连接请求后,调用者线程立刻可以朝下运行。当连接真正建立起来以后,socket底层会发送一个消息通知该对象。
这里 \提到执行部件和调用者通过三种途径返回结果:状态、通知和回调。可以使用哪一种依赖于执行部件的实现,除非执行部件提供多种选择,否则不受调用者控制。如果执行部件用状态来通知,那么调用者就需要每隔一定时间检查一次,效率就很低(有些初学多线程编程的人,总喜欢用一个循环去检查某个变量的值,这其实是一 种很严重的错误)。如果是使用通知的方式,效率则很高,因为执行部件几乎不需要做额外的操作。至于回调函数,其实和通知没太多区别
阻塞:阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在 得到结果之后才会返回。
有人也许会把阻塞调用和同步调用等同起来,实际上他是不同的。对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已。例如,我们在 CSocket中调用Receive函数,如果缓冲区中没有数据,这个函数就会一直等待,直到有数据才返回。而此时,当前线程还会继续处理各种各样的消息。如果主窗口和调用函数在同一个线程中,除非你在特殊的界面操作函数中调用,其实主界面还是应该可以刷新。
socket接收数据的另外一个函数 recv则是一个阻塞调用的例子。当socket工作在阻塞模式的时候,如果没有数据的情况下调用该函数,则当前线程就会被挂起,直到有数据为止。
非阻塞:非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。

上面这些概念都是教科书的概念,下面谈谈个人的理解。所谓同步就是当一个进程发起一个函数(任务)调用的时候,一直会到函数(任务)完成。进程继续往下执行。而异步这不会这样,异步情况下是当一个进程发起一个函数(任务)调用的时候,不会等函数返回,而是继续往下执行当,函数返回的时候通过状态、通知、事件。等方式通知进程任务完成。

而阻塞和非阻塞的概念相对明了多了。阻塞是当请求不能满足的时候就试进程挂起,非阻塞则是直接返回。

它们的组合:(网络装载)

图 2 给出了传统的阻塞 I/O模型,这也是目前应用程序中最为常用的一种模型。其行为非常容易理解,其用法对于典型的应用程序来说都非常有效。在调用 read 系统调用时,应用程序会阻塞并对内核进行上下文切换。然后会触发读操作,当响应返回时(从我们正 在从中读取的设备中返回),数据就被移动到用户空间的缓冲区中。然后应用程序就会解除阻塞(read 调用返 回)。

图 2. 同步阻塞 I/O 模型的典型流程

从应用程序的角度来说,read 调用会延续很长时间。实际上,在内核执行读操作和其他工作时,应用程序的确会被阻塞。

PS. 我理解这里的意思是,read请求是阻塞的,也没有异步通知机制,因为应用程序一直在这个过程中等待,即一直在主动查询,所以是同步的。(顺序)

同步非阻塞 I/O

同步阻塞 I/O 的一种效率稍低的变种是同步非阻塞 I/O。在这种模型中,设备是以非阻塞的形式打开的。这意味着 I/O 操作不会立即完成,read 操作可能会返回一个错误代码,说明这个命令不能立即满足(EAGAIN 或 EWOULDBLOCK),如图 3 所示。

图 3. 同步非阻塞 I/O 模型的典型流程


非阻塞的实现是 I/O 命令可能并不会立即满足,需要应用程序调用许多次来等待操作完成。这可能效率不高,因为在很多情况下,当内核执行这个命令时,应用程序必须要进行忙碌等待,直到数据可用为止,或者试图执行其他工作。正如图 3 所示的一样,这个方法可以引入 I/O 操作的延时,因为数据在内核中变为可用到用户调用 read 返回数据之间存在一定的间隔,这会导致整体数据吞吐量的降低。

PS. 我理解这里的意思是,read请求是非阻塞的,但是这里没有异步通知机制,而需要应用程序主动查询,所以是同步的。(多次试探)

异步阻塞 I/O

另外一个阻塞解决方案是带有阻塞通知的非阻塞 I/O。在这种模型中,配置的是非阻塞 I/O,然后使用阻塞 select 系统调用来确定一个 I/O 描述符何时有操作。使 select 调用非常有趣的是它可以用来为多个描述符提供通知,而不仅仅为一个描述符提供通知。对于每个提示符来说,我们可以请求这个描述符可以写数据、有读数据可用以及是否发生错误的通知。

图 4. 异步阻塞 I/O 模型的典型流程 (select)


select 调用的主要问题是它的效率不是非常高。尽管这是异步通知使用的一种方便模型,但是对于高性能的 I/O 操作来说不建议使用。

PS. 我理解这里的意思是,read请求实际上是非阻塞的,但是在异步通知方式上,采用了阻塞的slect系统调用,导致应用程序被阻塞,所以虽然异步,但任然阻 塞。(等待通知,自己完成)

异步非阻塞 I/O(AIO)

最后,异步非阻塞 I/O 模型是一种处理与 I/O 重叠进行的模型。读请求会立即返回,说明 read 请求已经成功发起了。在后台完成读操作时,应用程序然后会执行其他处理操作。当 read 的响应到达时,就会产生一个信号或执 行一个基于线程的回调函数来完成这次 I/O 处理过程。

图 5. 异步非阻塞 I/O 模型的典型流程


在一个进程中为了执行多个 I/O 请求而对计算操作和 I/O 处理进行重叠处理的能力利用了处理速度与 I/O 速度之间的差异。当一个或多个 I/O 请求挂起时,CPU 可以执行其他任务;或者更为常见的是,在发起其他 I/O 的同时对已经完成的 I/O 进行操作。

PS. 我理解这里的意思是,read请求实际上是非阻塞的,但是在异步通知方式上,采用了回调函数,无需应用程序再去处理。(委托完成)

异步 I/O 的动机

从前面 I/O 模型的分类中,我们可以看出 AIO 的动机。阻塞模型要求在 I/O 操作开始时阻塞应用程序,这意味着不可能同时重叠进行处理和 I/O 操作。同步非阻塞模型允许处理和 I/O 操作重叠进行,但是这需要应用程序根据重现的规则来检查 I/O 操作的状态。这样就剩下异步非阻塞 I/O 了,它允许处理和 I/O 操作重叠进行,包括 I/O 操作完成的通知。


这里我要特别强调一下异步IO和非阻塞IO的区别,异步IO就是把IO提交给系统,让系统替你做,做完了再用某种方式通知你;非阻塞IO就是你要通过某种方式不定时地向系统询问你是否可以开始做某个IO,当可以开始后,还是要自己来完成IO


分享到:
评论

相关推荐

    IO中同步、异步与阻塞、非阻塞的区别

    阻塞调用与同步调用不一样,同步调用时线程通常是激活状态,只是逻辑上没有返回。 B. 非阻塞 非阻塞调用则是指在结果未返回前,不会阻塞当前线程,而是会立即返回。线程不会处于等待状态,可以继续执行后续代码。...

    网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO

    这里我们将深入探讨同步IO、异步IO、阻塞IO和非阻塞IO的概念,理解它们的工作原理以及在实际应用中的差异。 1. 同步IO与异步IO: - **同步IO**:在同步模式下,应用程序执行I/O操作时会等待操作完成。这意味着程序...

    同步异步阻塞非阻塞

    同步异步阻塞非阻塞 IO 模型 在 Linux 环境下的网络 IO 中,有五种基本的 IO 模型:阻塞 IO、非阻塞 IO、IO 多路复用、信号驱动 IO 和异步 IO。其中,信号驱动 IO 不常用,因此主要介绍其余四种 IO 模型。 1. 阻塞...

    网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO.pdf

    同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出的答案都可能不同,比如wiki,就认为asynchronous IO和non...

    同步与异步--阻塞与非阻塞型IO

    根据I/O操作的不同特性,可以将其分为四大类:同步阻塞IO、同步非阻塞IO、异步阻塞IO以及异步非阻塞IO。本文将详细介绍这四种不同的I/O模型,帮助读者理解它们之间的差异及应用场景。 #### 二、同步阻塞IO 同步阻塞...

    同步、异步、阻塞、非阻塞的区别

    1. **同步阻塞**:最常见的组合之一,适用于简单且对实时性要求不高的应用场景。例如,使用阻塞式的方法读取文件或数据库查询。 2. **同步非阻塞**:虽然听起来有些矛盾,但实际上可以通过一些技术手段实现。例如,...

    详解socket阻塞与非阻塞,同步与异步、I/O模型

    Socket编程中的阻塞与非阻塞、同步与异步是两个独立的概念,它们涉及的是不同层面的操作机制。这里我们将详细探讨这两个概念以及I/O模型。 首先,同步与异步是客户端(C端)调用服务端(S端)时的行为模式。同步...

    JAVA IO同步,异步

    JAVA IO同步、异步详解 IO 操作是计算机系统中最基本的操作之一,它可以分为同步(Synchronous)和异步(Asynchronous)两种模式。...同时,我们还讨论了四种IO 模型:阻塞IO、非阻塞IO、IO 多路复用和异步IO。

    同步、异步IO

    同步IO和异步IO的主要区别在于如何处理数据传输时的等待时间。在同步IO中,当一个进程发起IO操作时,它会直接等待操作完成,这期间CPU会处于空闲状态,直到数据准备好才能继续执行后续代码。这种方式简单易懂,但...

    2-Socket阻塞与非阻塞,同步与异步、IO模型-120412发布1

    同步与异步决定了客户端等待服务器响应的方式,而阻塞与非阻塞则决定了服务器处理I/O操作的策略。选择正确的组合可以显著提高系统的并发性和响应能力,从而提升用户体验。在设计网络应用程序时,需要根据具体需求...

    简述JAVA同步、异步、阻塞和非阻塞之间的区别

    在IO操作中,我们可以将同步、异步、阻塞和非阻塞四种模式组合起来,形成四种不同的IO模式:同步阻塞IO、异步阻塞IO、同步非阻塞IO和异步非阻塞IO。同步阻塞IO是指Sender在发送请求后,等待Receiver的响应,直到...

    基于Python的gtornado异步IO设计源码,实现阻塞IO调用非阻塞化及协程风格使用

    本项目为基于Python的gtornado异步IO设计源码,共计包含26个文件,包括19个Python源文件、2个Markdown文件、1个.gitignore文件、1个YAML文件、1个LICENSE文件、1个文本文件、1个SQL文件。该源码旨在实现tornado框架...

    linux异步IO.pdf

    ### Linux异步IO详解 #### 引言 在Linux环境下,输入/输出(I/O)操作是系统资源管理和数据交互的核心部分。传统上,Linux采用的最常见I/O模型是同步I/O,其中应用程序在发出请求后会阻塞,直至请求完成。然而,...

    java 中同步、异步、阻塞和非阻塞区别详解

    异步与同步相对,它允许调用者在等待结果返回时继续执行其他任务。在Java中,通常通过回调、事件驱动或者Future/Await模型实现异步处理。异步处理可以提高程序响应速度,因为它避免了线程的阻塞等待,但同时也增加了...

    WinSock 异步IO模型

    与传统的同步IO模型不同,异步IO不会阻塞调用线程,而是通过事件通知或回调函数来指示操作的完成。 异步IO的核心概念包括: 1. **WSAAsyncSelect**:这是WinSock异步IO模型的一种实现方式,它允许应用程序指定一个...

    Python高级编程和异步IO并发编程

    最后,异步IO(非阻塞IO)和协程是Python并发编程的高级主题。Python的asyncio库提供了一种事件驱动的编程模型,通过async/await关键字实现协程,可以实现高效的并发执行,特别适用于I/O密集型任务。理解事件循环、...

    异步IO之事件选择模型使用说明_高并发_vcsocket异步IO_

    **VC++与VCsocket异步IO:** 在Windows平台上,Visual C++(简称VC++)提供了对异步I/O的良好支持,特别是通过使用完成端口(Completion Port, CP)。完成端口是一种I/O完成机制,它将I/O操作的结果与特定线程关联...

    4-【Linux网络编程】同步,异步,阻塞,非阻塞-1809261

    【Linux网络编程】同步、异步、阻塞与非阻塞的概念在计算机科学特别是网络编程领域至关重要。在Linux环境下,理解和运用这些概念对于优化应用程序性能和处理并发I/O至关重要。 同步(Synchronous)I/O指的是应用...

    异步IO模型编程实例(纯C语言)

    异步IO模型是指在进行IO操作时,不会阻塞当前线程或进程,而是将IO操作交由操作系统或专门的IO处理线程处理,从而提高系统的并发性和响应速度。在Windows平台上,异步IO模型主要通过select函数、WSAAsyncSelect函数...

Global site tag (gtag.js) - Google Analytics