猿问

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

单线程非阻塞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模型以一种简单的方式?如果你能帮我,我会很感激的。*)


qq_遁去的一_1
浏览 839回答 3
3回答

BIG阳

好的,为了给出一些透视图,让我将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抽象的线程:打开到db的连接,就可以异步地建立连接本身。连接db后,查询将传递给服务器。查询可以排队。主事件循环通过回调或事件得到完成通知。主循环执行回调/均衡器。对http服务器的传入请求以类似的方式处理。内部线程体系结构如下所示:C+线程是执行异步I/O(磁盘或网络)的libuv线程。主事件循环在将请求分派到线程池后继续执行。它可以接受更多的请求,因为它不等待或睡眠。SQL查询/HTTP请求/文件系统读取都是这样发生的。

繁星淼淼

Node.js使用利布夫幕后。利布夫有一个线程池(默认情况下大小为4)。因此,node.js使用线程实现并发。不过,&nbsp;你的代码运行在单个线程上(也就是说,Node.js函数的所有回调都将在同一个线程上调用,即所谓的循环线程或事件循环)。当人们说“Node.js运行在单个线程上”时,他们实际上是在说“Node.js的回调运行在单个线程上”。
随时随地看视频慕课网APP

相关分类

Node.js
我要回答