网络系统 - "阻塞"和"非阻塞"协议之间的区别是什么?

Dar*_*lar 8 networking network-protocols

在计算机网络中 - 实际上在很多其他领域 - 我听到很多关于术语"阻塞","非阻塞","同步"和"异步"的引用.我想知道是否有人能用非常直接/简单的术语解释这些意味着什么?

BRP*_*ock 8

"阻塞"调用"阻止"调用它的程序直到它完成.在下一个语句运行之前,您的程序必须等待它(无论如何).大多数函数调用都是"阻塞",例如,set x to 4 + 4在计算8并赋值给它之前,它不会继续执行下一个语句x.同样,阻塞或同步网络方法将阻止调用程序直到它完成.在诸如"将数据包发送到远程系统"之类的情况下,这个时间可以在几秒或更长时间内测量,而不是算术消耗的微秒(或更少).

相反,"非阻塞"或异步方法通常将其结果存储在某种"邮箱"或"队列"中,或者(更常见地)将回调您在完成时提供的功能.对于在等待相对较慢的网络进程完成时执行任何其他操作(例如,显示用户界面)的程序,这通常/通常更好.

当访问相对较快的本地服务(如本地磁盘I/O),一台计算机上的进程间通信或将输出发送到本地显示器时,阻塞I/O有时是首选,因为它更容易编写.

阻止网络I/O的示例:

set web-page to (the result of) get url "http://www.google.com/"
in web-page, find <title>...</title>,
     assign this to google-title;
if not found,
     present a warning, and
     set google-title to "Google"
do something else…
Run Code Online (Sandbox Code Playgroud)

与:

get url "http://www.google.com/" and call back google-title-callback
do something else…

function google-title-callback, accepts web-page:
    in web-page, find <title>...</title>,
         assign this to google-title;
    if not found,
         present a warning, and
         set google-title to "Google"
Run Code Online (Sandbox Code Playgroud)

异步I/O几乎总是在应用程序级别用于GUI编程.例如,基于终端(流)的程序可能同步等待用户输入,而GUI程序可能是异步的,允许您随机选择各种控件或执行其他操作(如调整窗口大小),要求它接受消息通过回调方法或事件处理程序的各种时间,或多或少相当于上面的网络回调示例相同类型的事物.


alp*_*ero 5

根本问题是什么?

IO子系统通常比简单指令处理(在CPU中)具有更大的延迟.这种延迟也是非确定性的(当然在已知范围内).

IO子系统通常(全部?)独立于系统处理器.虽然这是积极的,因为它允许在系统的不同(hw)组件中进行并发操作,但它也强调了系统总体上还需要通过提供数据和控制信息传输来耦合不同的IO和CPU组件.

作为概括,我们讨论的是协作互连(活动)组件.通常这是主/从关系,但这不是一般情况,例如,这也适用于对等连接.

+-----+                 +-----------+
| dev | <==== DATA ====>| processor |
|     | <---- ctrl -----| <master>  |
+-----+                 +-----------+
Run Code Online (Sandbox Code Playgroud)

(请注意,"设备"可以是内存,网络,磁盘或其他进程.此外,此处有3个子系统,两个对等体之间的"总线"或"连接"也是一个具有延迟,带宽,容量的系统等)

术语同步,异步,阻塞非阻塞,解决和定义两个链接组件之间的通信/互连语义.

  • 阻止和不阻止

这些术语解决了调用语义.

在阻塞调用中,启动交换的组件会暂停所有活动,直到控制和/或数据传输到另一个组件完成为止.

在非阻塞调用中,启动交换的组件基本上执行着火并且(可能)忘记.

  • 同步和异步

这些术语涉及交互模式(协议).

在同步交互中,两个组件将以锁定步骤操作,并且交互是完全确定的. 从根本上说,我们可以说在组件之间的同步交换中会发生已知的,确定性的和有限的一组动作.

在异步交互中,两个组件不在锁步中协调(因此称为异步). 从根本上说,我们可以说在完成交换过程中,任何一个组件都可能发生一系列未知的操作.

它可能会澄清对这些术语附加"响应",例如"同步 - 响应",因为这既完全阐明了一般概念,又消除了阻塞的同步(这是一个常见的概念错误).

  • 注意

除此之外,显然我们有一个系统设计空间,它是排列的{block, non-block} X {synch, asynch}.例如,系统可以使用具有异步协议的非阻塞调用语义.

讨论

一般来说,可以公平地说,我们人类程序员更喜欢顺序和完全确定性的模型:坦率地说,它们更容易受孕,发展或理解.

但是,作为系统极客,我们也喜欢效率性能,对吧?

根据上面的图表,我们注意到3个不同的(和两个独立的)子系统.如果上面的'处理器'可以告诉'总线''将xyz发送到开发'并且等到总线说"好的话,我做了那个",这不是很好吗?这将是一个非阻塞的电话.(注意它不以任何方式解决同步或异步协议!)

另外,如果"处理器"在等待响应完成交换时需要做其他工作,整个系统会受益吗?这将是一次异步交换.