单线程无阻塞IO模型在Node.js中的工作方式

Wenhao Ji

我不是Node程序员,但是我对单线程无阻塞IO模型的工作方式感兴趣在阅读了理解理解节点事件循环文章之后,我对此感到非常困惑。它给出了该模型的示例:

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等待的sleeping语句。并且该程序被困在I/O等待中,并且无法执行使网页落后的代码。在等待期间程序会切换到请求B吗?我认为,由于是单线程模型,因此无法将一个请求与另一个请求进行切换。但是示例代码的标题表明,除了您的代码之外所有其他内容都可以并行运行

(PS,因为我从未使用过Node,所以不确定是否会误解代码。)在等待期间,Node如何将A切换到B?您能否以简单的方式解释Node的单线程无阻塞IO模型如果您能帮助我,我将不胜感激。:)

乌塔尔

Node.js建立在libuv上libuv是一个跨平台的库,为支持的操作系统(至少为Unix,OS X和Windows)提供的异步(非阻塞)输入/输出抽象api / syscall。

异步IO

在此编程模型中,对由文件系统管理的设备和资源(套接字,文件系统等)的打开/读取/写入操作不会阻塞调用线程(如在典型的类似c的同步模型中),而只是标记当有新数据或事件可用时,将通知该进程(在内核/ OS级数据结构中)。如果是类似Web服务器的应用程序,则该过程负责确定通知事件属于哪个请求/上下文,并从那里继续处理请求。请注意,这必然意味着您将与向OS发出请求的堆栈位于不同的堆栈框架上,因为OS必须屈服于进程的调度程序才能使单线程进程处理新事件。

我描述的模型的问题在于,它对程序员不熟悉并且很难推理,因为它本质上是非顺序的。“您需要在函数A中发出请求,并在另一个函数中处理结果,而在该函数中,通常无法使用来自A的本地人。

节点的模型(继续传递样式和事件循环)

Node通过诱使程序员采用某种编程风格,利用javascript的语言功能解决了该问题,使该模型看起来更具同步性。每个请求IO的函数都具有类似的签名,function (... parameters ..., callback)并且需要给其提供一个回调,该回调将在请求的操作完成时被调用(请注意,大部分时间都在等待OS发出完成信号,这是可以花费的时间。花了其他工作)。Javascript对闭包的支持使您可以使用在回调主体内部的外部(调用)函数中定义的变量-这样可以保留节点运行时将独立调用的不同函数之间的状态。另请参见继续传递样式

而且,在调用产生了IO操作的函数之后,调用函数通常将return控制到节点的事件循环此循环将调用计划执行的下一个回调或函数(很可能是由于操作系统通知了相应的事件),这将允许并发处理多个请求。

您可以认为节点的事件循环有点类似于内核的调度程序:内核将在其未完成的IO完成后调度执行阻塞的线程,而节点将在发生相应事件时调度回调。

高度并发,无并行

最后,短语“除了代码之外的所有内容并行运行”在捕获节点这一点上做得很不错,该节点允许您的代码通过多路复用和排序所有js并发一个线程同时处理来自成千上万个开放套接字的请求单个执行流中的逻辑(即使说“一切并行运行”在这里可能不正确-请参阅并发与并行-有什么区别?)。这对于webapp服务器非常有效,因为实际上大部分时间都花在等待网络或磁盘(数据库/套接字)上,并且逻辑实际上并不需要占用CPU过多的资源-也就是说:这对于IO受限的工作负载非常有效

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Java中的单线程异步处理

Threadpool如何重用线程及其工作方式

为什么Node.js是单线程的?

Node.js-单线程,非阻塞?

如果node.js是单线程的,那么server.listen()为什么返回?

node.js单线程模型如何处理并发请求?

当节点为单线程时,为什么在node.js中需要连接池?

“公牛”是否利用多核,因为node.js运行单线程

node.js集群,redis,单线程和非阻塞I / O如何工作?

Node.js如何同时异步和单线程?

Python中的多处理比单线程慢

符号状态探索在符号模型检查中的工作方式

在单线程单元模型中,是否同步了对方法的任何调用?

Flex在facebook.io和实际应用程序React Native中的工作方式不同

单线程Node.js如何同时处理请求?

Node.js单线程与并发

与indexOf在JS中的工作方式混淆

单线程程序是否在CPU中并行执行?

JS中无名导入和导出的工作方式

当JavaScript是单线程语言时,如何在JavaScript中实现异步无阻塞代码?

matplotlib在简单线程中绘制冻结

Node.JS中的单线程事件循环与多线程非阻塞工作者

尝试在C ++中创建简单线程时出错

Linux,Unix,Solaris中的线程工作方式是否有所不同

如何在node.js中创建后台单线程FIFO作业队列

多核CPU与Java(Tomcat)上的单线程Node.js

ruby 中的多线程比单线程慢

单线程工作和多线程不工作

为什么 setTimeout 和 setInterval 在浏览器和 Node.js 中的工作方式不同?