事件驱动和基于线程的服务器系统有什么区别?

时间:2014-08-13 07:14:52

标签: multithreading node.js threadpool event-driven

  • Node.js 是一个事件驱动的I / O,它是一个单线程服务器, 作用于回调并且永远不会阻塞主线程。

    1. 但它如何设法实现非阻塞I / O?
    2. 如果它易于管理,为什么不基于线程的系统管理呢?
    3. 不能像其他线程一样(在单个事件驱动的线程后面)像基于线程一样吗?
    4. 如果其他线程意味着工作人员(在事件驱动线程之后)很忙,那么它如何在不阻塞的情况下处理作业呢?
  • 基于线程的模型将任务分配给线程,如果没有 空闲线程,阻止新任务。

    1. 如果一个线程可以处理多个任务,比如事件驱动的单个任务 处理每个I / O而不阻塞的线程,为什么基于线程 如果没有,系统不会在繁忙的线程上使用此策略 阻塞。

我想知道事件驱动和基于线程的服务器系统之间有什么区别(优点/缺点)。

1 个答案:

答案 0 :(得分:32)

差异可能如下所述(有一些简化):

  • 在“线程驱动”运行时,当请求进入时,会创建一个新线程,并在该线程中完成所有处理。

  • 在“事件驱动”运行时,当请求进入时,事件被调度并且处理程序将接收它。什么时候?在Node.js中,有一个“事件循环”,它基本上遍历需要执行的所有代码片段并逐个执行。因此,一旦事件循环调用它,处理程序将处理该事件。这里重要的是所有处理程序都在同一个线程中调用 - 事件循环没有要使用的线程池,它只有一个线程。

在“事件驱动”模型中,如果处理程序需要很长时间才能完成(即通过内部计算密集的for循环),那么在此期间不会处理任何其他请求,因为事件循环不会在当前处理程序完成之前调用下一个处理程序。由于Javascript的异步特性,这通常不是问题。

另一方面,在“线程驱动”模型中,如果处理程序需要花费大量时间来完成,那么它不会对其他线程产生太大影响,因为它们可以独立地同时运行。

不幸的是,创建一个新线程会增加一些开销,如果你需要处理数千个并发连接,它可能会成为一种负担。这就是Node.js被认为是快速的原因 - 无论你处理多少个连接,都只有一个线程1。你只需要小心不要阻止任何处理程序来保持移动。幸运的是,大多数情况下编写阻塞JavaScript代码并不容易。

同样重要的是要注意在大多数运行时都可以编写异步代码。它已成为Node.js中使用最广泛的,因为Javascript的性质。多亏了这一点,几乎您在Node中使用的每个库都将是异步的。

有关事件循环的说明,请参阅this article (and pictures)

1当然,Node.js进程中有一个线程,其中一些与I / O有关。但是你的app逻辑是在一个线程中处理的。