有什么区别:异步,非阻塞,事件基础架构?

nic*_*ckb 77 asynchronous programming-languages event-based-programming nonblocking blocking

  1. 有什么区别:

    • 异步,
    • 非阻止,和
    • 基于事件的架构?
  2. 可以是异步非阻塞(以及基于事件的)吗?

  3. 在编程中最重要的是拥有一些东西:异步,非阻塞和/或事件库(或全部3)?

如果你能提供一些例子,那就太棒了.

这个问题正在被问到,因为我正在阅读关于类似主题的这篇伟大的StackOverflow文章,但它没有回答我上面的问题.

小智 80

异步 异步字面意思是不同步.电子邮件是异步的 您发送邮件,您不希望现在得到回复.但它不是非阻塞的.本质上它意味着一种架构,其中"组件"彼此发送消息而不期望立即响应.HTTP请求是同步的.发送请求并获得回复.

非阻塞 此术语主要用于IO.这意味着当你进行系统调用时,它会立即返回它所拥有的任何结果,而不会使你的线程进入睡眠状态(很有可能).例如,非阻塞读/写调用以他们可以做的任何方式返回,并期望调用者再次执行调用.try_lock例如是非阻塞调用.只有在可以获取锁定时它才会锁定.系统调用的常用语义是阻塞的.read将等到它有一些数据并将调用线程置于休眠状态.

事件基础 这个术语来自libevent.非阻塞读/写调用本身是无用的,因为他们不会告诉你"何时"你应该回拨(重试).select/epoll/IOCompletionPort等是从"OS"中找出这些调用预期返回"有趣"数据的不同机制.libevent和其他类似的库为各种操作系统提供的这些事件监视工具提供了包装器,并提供了一致的API来与跨操作系统的运行一起工作.非阻塞IO与Event-base密切相关.

我认为这些术语重叠.例如,HTTP协议是同步的,但使用非阻塞IO的HTTP实现可以是异步的.同样,像read/write/try_lock这样的非阻塞API调用是同步的(它会立即给出响应),但"数据处理"是异步的.

  • 我发送电子邮件时如何阻止,但不期待答案?在等待回复的同时,我可以开始关注自己的事业. (4认同)
  • 关于非阻塞的优点是需要不断轮询,而异步可以基于推送。 (2认同)

sup*_*cat 19

在异步硬件中,代码要求某个实体做某事,并在动作完成时自由地做其他事情; 一旦动作完成,实体通常会以某种方式发出代码信号.非阻塞体系结构将记录代码可能感兴趣的自发发生的操作,并允许代码询问这些操作发生了什么,但代码只有在明确询问这些操作时才会知道这些操作.当事件自发发生时,基于事件的体系结构将肯定地通知代码.

考虑一个串行端口,代码将从该端口接收1,000个字节.

在阻塞读取架构中,代码将等待,直到1,000个字节到达或者它决定放弃.

在异步读取架构中,代码将告诉驱动程序它需要1,000个字节,并在1,000个字节到达时通知.

在非阻塞体系结构中,代码可以随时询问已经到达了多少字节,并且在它认为合适时可以读取任何或所有这样的数据,但是它知道所有数据何时到达的唯一方法是询问; 如果代码想要在第1000个字节到达的四分之一秒内找到它,它必须每隔四分之一秒检查一次.

在基于事件的体系结构中,串行端口驱动程序将在任何数据到达时通知应用程序.驱动程序不知道应用程序需要多少字节,因此应用程序必须能够处理小于或大于应用程序所需数量的通知.


use*_*272 5

所以要回答你的第一和第二个问题:

非阻塞实际上与异步相同——您进行调用,稍后您将得到结果,但是在发生这种情况时,您可以做其他事情。阻塞则相反。在继续您的旅程之前,您等待电话返回。

现在异步/非阻塞代码听起来非常棒,确实如此。但我有警告的话。在受限环境(例如手机)中工作时,异步/非阻塞非常有用……请考虑有限的 CPU/内存。它也适用于前端开发,您的代码需要以某种方式对 UI 小部件做出反应。

异步是所有操作系统如何工作的基础——它们在后台为你完成工作,并在完成你的要求后唤醒你的代码,当调用失败时,你被告知它没有通过异常或某种返回代码/错误对象工作。

当您的代码要求一些需要一段时间才能响应的内容时,您的操作系统知道它可能会忙于做其他事情。您的代码 - 一个进程、线程或等价物,会阻塞。您的代码在等待建立网络连接时,或在等待来自 HTTP 请求的响应时,或在等待读/写文件时,完全不知道操作系统中发生的其他事情,以及很快。您的代码可能“只是”等待鼠标点击。那段时间实际发生的事情是您的操作系统正在无缝地管理、调度和响应“事件”——操作系统正在寻找的东西,例如管理内存、I/O(键盘、鼠标、磁盘、互联网),其他任务、故障恢复等。

操作系统是他妈的硬核。他们真的很擅长向程序员隐藏所有复杂的异步/非阻塞的东西。这就是大多数程序员如何通过软件达到我们今天的水平。现在我们达到了 CPU 限制,人们说可以并行完成一些事情以提高性能。这意味着异步/非阻塞似乎是一件非常有利的事情,是的,如果您的软件需要它,我可以同意。

如果您正在编写后端 Web 服务器,请谨慎操作。请记住,您可以以更便宜的价格水平扩展。Netflix/亚马逊/谷歌/Facebook 显然是这条规则的例外,纯粹是因为他们使用更少的硬件更便宜。

我会告诉你为什么异步/非阻塞代码是后端系统的噩梦......

1)它变成了对生产力的拒绝服务......你必须多想,并且在此过程中犯了很多错误。

2) 反应式代码中的堆栈跟踪变得不可破译——很难知道什么叫什么、什么时候、为什么和如何。祝调试顺利。

3)您必须更多地考虑事情是如何失败的,尤其是当许多事情与您发送它们的方式不符时。在旧世界,你一次只做一件事。

4)更难测试。

5)更难维护。

6) 很痛苦。编程应该是一种快乐和乐趣。只有受虐狂才喜欢痛苦。编写并发/反应式框架的人是虐待狂。

是的,我已经写了同步和异步。我更喜欢同步,因为 99.99 的后端应用程序可以使用这种范例。毫无疑问,前端应用程序需要反应式代码,而这一直都是如此。

  1. 是的,代码可以是异步的、非阻塞的和基于事件的。

  2. 编程中最重要的事情是确保您的代码在可接受的时间内工作并做出响应。坚持这个关键原则,你就不会出错。