asynchronous非阻塞事件驱动方法是“asynchronous编程”的唯一方法吗?

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

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

事件驱动方法是做“asynchronous编程”的唯一方法吗?

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

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

evented和non-eventedasynchronous编程之间的区别在于,evented编程是一个低层次的non-evented风格的包装,它简化了关于在什么情况下可能发生的事情的推理,并有助于限制堆栈深度。

  1. 放松的推理 :假设你正在编写一个程序来完成一些I / O,并在I / O完成时发送一个信号。 在您的信号处理程序中,您可以立即处理该I / O,但是您必须小心处理程序中的操作。 例如,如果你需要locking,你必须知道被中断的线程(你刚收到的那个线程)没有拿着锁,否则你会立即造成死锁。 另外,如果您抓住锁,然后另一个I / O完成,会发生什么? 另外,如果被信号中断的线程是非常高的优先级,并且你的处理程序导致它等待很长时间,会发生什么? 基本上答案是:“不要做任何需要信号处理器同步的东西。” 事件编程通过将事件添加到信号处理程序中的队列然后退出,从而允许线程在稍后时间出列和处理事件来实现此目的。

  2. 限制堆栈深度 :正如我已经提到的那样,多个信号处理程序可以同时在同一个堆栈上运行(后面的程序会中断早期的堆栈)。 如果您经常收到信号,您可能会陷入堆栈溢出的不幸位置。 出于这个原因,保持信号处理程序短而甜,是一个非常好的主意。 偶数编程通过仅执行一个简单的操作就可以实现这一点:将任务添加到队列中。

编程的缺点是如果天真地使用它,速度可能会变慢。 例如,假设你的任务非常大,但是每隔一段时间用户按一个button,一个字母应该出现在屏幕上。 如果在信号处理程序中按下button,则可以立即显示在屏幕上。 如果将其添加到队列中,可能需要一段时间才能实际处理button按下事件。 你可以在一些编程框架中给予事件优先级来处理这个问题,但最好的做法是保持你的所有任务都很短,并且在一个单独的线程池中运行任何长时间运行的任务。 这(其他原因)是为什么evented框架几乎总是依赖于asynchronousI / O。