Node.js中的单线程和事件循环

首先,我首先尝试了解什么是Node.Js。 我有两个问题。

第一个问题
从费利克斯的文章中,它表示“同时只能有一个callback触发,在callback完成执行之前,所有其他的callback都必须排队等候”。

然后,考虑下面的代码(从nodejs官方网站复制)

var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); }).listen(8124, "127.0.0.1"); 

如果同时收到两个客户端请求,则表示以下工作stream程:

  1. 首先接收到http请求事件,接收到第二个请求事件。
  2. 一旦收到第一个事件,第一个事件的callback函数正在执行。
  3. 同时,第二个事件的callback函数必须等待。

我对吗? 如果我是对的, Node.js如何在非常短的时间内控制数千个客户端请求。

第二个问题
术语“事件循环”主要用在Node.js主题中。 我从http://www.wisegeek.com/what-is-an-event-loop.htm了解了“事件循环”

事件循环(或主循环)是程序中的一个构造,它控制和分派事件之后的事件。

初始事件可以是任何东西,包括按下键盘上的button或点击程序上的button(在Node.js中,我认为最初的事件将是http请求,db查询或I / O文件访问)。

这被称为循环,不是因为事件连续发生,而是因为循环准备事件,检查事件,调度事件,并重新从头开始。

我对第二段特别是“ 重复这个过程 ”这个短语有冲突。 我接受上面的问题上面的http.createServer代码是绝对“事件循环”,因为它重复监听http请求事件。

但是我不知道如何识别下面的代码是事件驱动还是事件循环。 除了db查询完成后触发的callback函数,它不会重复任何操作。

 database.query("SELECT * FROM table", function(rows) { var result = rows; }); 

请让我听听你的意见和答案。

答案一 ,你的逻辑是正确的:第二个事件将等待。 并将执行到排队的callback时间。

同样,请记住,在技术世界中不存在“同时”这样的事情。 一切都有非常特定的地点和时间。

node.jspipe理数以千计的连接的方式是,当有一些数据库调用阻塞逻辑,或者另一个IO操作正在处理(例如stream)时,不需要保持线程空闲状态。 它可以“服务”第一个请求,也许创造更多的callback,并继续其他。
因为没有办法阻止执行(除了(真正的)和类似的废话之外),所以在整个应用程序逻辑上传播实际资源变得非常有效率。

线程 – 很昂贵,线程的服务器容量与可用内存直接相关。 所以大多数经典的Web应用程序会受到影响,因为只有在数据库查询块或类似的数据库查询块处于空闲状态时才使用RAM。 在节点,这不是一个案件。

不过,它允许通过cluster创build多个线程(如child_process),从而扩展了更多的可能性。

答案二 没有你可能想到的“循环”这样的东西。 幕后不会有循环检查是否有连接或任何数据收到等。 现在也是由Async方法来处理的。

所以从应用的angular度来看,没有“主循环”,从开发人员的angular度来看,事件驱动(而不是事件循环)是一切。

如果使用http.createServerhttp.createServercallback绑定为对请求的响应。 所有的套接字操作和IO的东西都会在幕后发生,以及HTTP握手,parsing标题,查询,参数等等。 一旦发生在幕后,工作完成,它将保留数据,并将一些数据推回到事件循环。 一旦事件循环病是免费的,将来得及的时候,它将在node.js应用程序上下文中执行您的callback与来自幕后的数据。

数据库请求 – 同样的故事。 它不善于准备和询问内容(可能会再次asynchronous),然后一旦数据库响应,数据将为应用程序上下文准备callback。

说实话,你只需要了解node.js的概念,而不是实现事件。 最好的办法就是做实验。

1)是的,你是对的。

这是有效的,因为你对节点所做的一切主要是I / O绑定的。

当一个新的请求(事件)进入时,它被放入一个队列中。 在初始化时,Node分配一个ThreadPool,负责为I / O绑定处理产生线程,比如networking/套接字调用,数据库等(这是非阻塞的)。

现在,您的“callback”(或事件处理程序)速度非常快,因为您正在做的大部分操作很可能是CRUD和I / O操作,而不是CPU密集型操作。

因此,这些callback给人的感觉是它们并行处理,但实际上并不是,因为实际的并行工作是通过ThreadPool(使用multithreading)完成的,而callback本身只是接收结果从这些线程,使处理可以继续,并发送回应客户端。

你可以很容易地validation这一点:如果你的callback是CPU任务繁重,那么你可以肯定,你将无法处理每秒数以千计的请求,并且与multithreading系统相比,它的缩减效果非常差。

2)你是对的,再次。

不幸的是,由于所有这些抽象,你必须下潜,以了解背景中发生了什么。 但是,是的,有一个循环。

特别的,Nodejs是通过libuv实现的。

有趣的阅读 。

但是我不知道如何识别下面的代码是事件驱动还是事件循环。 除了db查询完成后触发的callback函数,它不会重复任何操作。

事件驱动是一个通常在有事件循环时使用的术语,它意味着一个由诸如点击button,数据到达等事件驱动的应用程序。通常,您会将callback关联到这些事件。