【问题标题】:Is asynchronous non-blocking event driven approach the only way to "asynchronous programming"? [closed]异步非阻塞事件驱动方法是“异步编程”的唯一途径吗? [关闭]
【发布时间】:2013-05-17 20:52:18
【问题描述】:

我对这里的术语有点困惑。让一个程序由一些概念上不同的任务组成:

在异步编程模型中,任务相互交错,但在一个控制线程中。即使在多处理器系统上,单线程异步系统也将始终以交错方式执行。没有实际的并行性。

事件驱动的方法是进行“异步编程”的唯一方法吗?

【问题讨论】:

  • 这听起来更像是一个讨论而不是一个实际的问题。你认为会是什么答案?另一种方法?他们的名单? (为此,您仍然必须定义“异步编程”。为什么线程不是异步编程的一种方法?)
  • 另外,我建议你看看 Erlang 是做什么的。几乎该语言的全部意义在于实现用于建模并发性的架构,这是通过让潜在的独立任务或参与者交换消息作为共享数据的唯一方式来完成的。这些是在多个线程上协同调度的。这可能与 Node.js 风格不同,后者涉及显式延续;或者它可能被视为同一件事,因为您仍然有一个任务“告诉”另一个任务何时继续。 (高层架构概念含糊不清。)
  • 所以我想你的问题读作要求我们将草莓与黄瓜进行比较。在植物学上它们都是水果(甚至是浆果),在烹饪上它们是天壤之别。因此,甚至不清楚哪种标准与您提到的方法不同,因为您总是可以得出细微的相似之处或发现细微的差异。
  • 你从哪里复制的那句话?从什么时候开始“异步编程模型”要求“单线程控制”?我可能会打开“node.JS”闪光灯,但通常不会。

标签: multithreading node.js events asynchronous concurrency


【解决方案1】:

简短的回答是:还有其他方法。

长答案:这取决于您使用的是什么技术。例如,JS 不提供任何非事件异步方法(至少,我知道)。但是,在 C 和许多其他语言中,您可以在用户进程中使用信号来进行异步编程。

事件和非事件异步编程之间的区别在于,事件编程是对较低级别的非事件样式的封装,它简化了在什么上下文中可能发生的事情的推理,并有助于限制堆栈深度。

  1. 轻松推理:假设您正在编写一个执行某些 I/O 并在 I/O 完成时发送信号的程序。在您的信号处理程序中,您可以立即处理该 I/O,但您必须小心您在处理程序中所做的事情。例如,如果你需要一个锁,你必须知道被中断的线程(你刚刚征用其堆栈的那个线程)没有持有锁,否则你会立即导致死锁。另外,如果你抓住锁然后另一个 I/O 完成会发生什么?另外,如果被信号中断的线程具有很高的优先级并且您的处理程序导致它等待很长时间,该怎么办?基本上答案是:“永远不要在信号处理程序中做任何需要同步的事情。”事件编程通过将事件添加到信号处理程序中的队列然后退出来实现这一点,允许线程出列并在以后处理事件。

  2. 限制堆栈深度:正如我已经提到的,多个信号处理程序可以同时在同一个堆栈上运行(后面的中断前面的)。如果您经常收到信号,您可能会陷入堆栈溢出的不幸境地。出于这个原因,让信号处理程序保持简短和甜蜜是一个非常好的主意。事件编程通过只做一个非常简单的操作来实现这一点:将任务添加到队列中。

事件编程的缺点是,如果天真地使用它可能会变慢。例如,假设您的任务非常大,但每隔一段时间用户按下一个按钮,屏幕上就会出现一个字母。如果您在信号处理程序中处理按钮按下,它可以立即出现在屏幕上。如果将其添加到队列中,可能需要一段时间才能真正处理按钮按下事件。您可以在某些事件编程框架中赋予事件优先级来处理这个问题,但最佳实践是让所有事件任务非常短,并在单独的线程池中运行任何长时间运行的东西。这(以及其他原因)是事件框架几乎总是依赖异步 I/O 的原因。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2018-04-06
  • 2013-05-07
  • 2020-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-03
  • 2016-03-05
相关资源
最近更新 更多