为了账号安全,请及时绑定邮箱和手机立即绑定

单线程非阻塞IO模型是如何在Node.js中工作的

单线程非阻塞IO模型是如何在Node.js中工作的

qq_遁去的一_1 2019-06-28 15:24:12
单线程非阻塞IO模型是如何在Node.js中工作的我不是Node程序员,但我感兴趣的是单线程非阻塞IO模型起作用了。在我读了这篇文章之后理解-节点-js-事件循环我真的很困惑。它给出了一个模型的例子:c.query(    'SELECT SLEEP(20);',    function (err, results, fields) {      if (err) {        throw err;      }      res.writeHead(200, {'Content-Type': 'text/html'});      res.end('<html><head><title>Hello</title></head><body><h1>Return from async DB query</h1></body></html>');      c.end();     });这里有个问题。当有两个请求A(首先)和B,因为只有一个线程,服务器端程序将首先处理请求A:执行SQL查询,这是一个代表I/O等待的睡眠语句。程序被放置在I/O等待时,无法执行呈现网页后面的代码。在等待过程中,程序会切换到请求B吗?在我看来,由于单线程模型,无法从另一个请求切换。但是示例代码的标题是“除了您的代码之外,所有东西都是并行运行的”。(我不知道我是否误解了代码,因为我从未使用过Node。)在等待过程中节点如何切换A到B?你能解释一下吗单线程非阻塞IO模型以一种简单的方式?如果你能帮我,我会很感激的。*)
查看完整描述

3 回答

?
BIG阳

TA贡献1859条经验 获得超6个赞

好的,为了给出一些透视图,让我将node.js与Apache进行比较。

Apache是一个多线程HTTP服务器,对于服务器接收的每个请求,它都会创建一个单独的线程来处理该请求。

另一方面,Node.js是事件驱动的,从单个线程异步处理所有请求。

当在Apache上接收到A和B时,将创建两个处理请求的线程。每个单独处理查询,每个在服务页面之前等待查询结果。只有在查询完成之前才能使用该页面。由于服务器在收到结果之前无法执行其余的线程,所以查询FETCH处于阻塞状态。

在节点中,C.Query是异步处理的,这意味着当c.query为A获取结果时,它跳到处理B的c.query,当结果到达A时,将结果发送回调,后者发送响应。js知道在提取完成时执行回调。

在我看来,因为它是一个单线程模型,所以无法从一个请求切换到另一个请求。

实际上,节点服务器一直都是这样做的。要使开关(异步行为),您要使用的大多数函数都会有回调。

编辑

SQL查询从MySQL图书馆。它实现回调样式以及事件发射器来排队SQL请求。它不异步执行它们,这是由内部利布夫提供非阻塞I/O抽象的线程:

  1. 打开到db的连接,就可以异步地建立连接本身。
  2. 连接db后,查询将传递给服务器。查询可以排队。
  3. 主事件循环通过回调或事件得到完成通知。
  4. 主循环执行回调/均衡器。

对http服务器的传入请求以类似的方式处理。内部线程体系结构如下所示:


C+线程是执行异步I/O(磁盘或网络)的libuv线程。主事件循环在将请求分派到线程池后继续执行。它可以接受更多的请求,因为它不等待或睡眠。SQL查询/HTTP请求/文件系统读取都是这样发生的。


查看完整回答
反对 回复 2019-06-28
?
繁星淼淼

TA贡献1775条经验 获得超11个赞

Node.js使用利布夫幕后。利布夫有一个线程池(默认情况下大小为4)。因此,node.js使用线程实现并发。

不过你的代码运行在单个线程上(也就是说,Node.js函数的所有回调都将在同一个线程上调用,即所谓的循环线程或事件循环)。当人们说“Node.js运行在单个线程上”时,他们实际上是在说“Node.js的回调运行在单个线程上”。


查看完整回答
反对 回复 2019-06-28
  • 3 回答
  • 0 关注
  • 838 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信