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

erg*_*ran 25 multithreading event-driven threadpool node.js

  • Node.js是一个事件驱动的I/O,它是一个单线程服务器,它作用于回调,从不在主线程上阻塞.

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

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

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

kam*_*uel 37

差异可能描述如下(通过一些简化):

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

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

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

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

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

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

有关事件循环的说明,请参阅此文章(和图片).

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

  • 如果服务器使用线程池,“当请求进来时,就会创建一个新线程”,这不是一个真实的说法 (6认同)