我描述的模型的问题在于,它对程序员不熟悉且难以推理,因为它本质上是非顺序的. 您需要在函数A中进行请求,并在另一个函数中处理结果,而通常情况下,您无法使用函数A中的本地人." 节点的模型(继续传递样式和事件循环) Node通过诱使程序员采用某种编程风格,利用javascript的语言功能解决了该问题,使该模型看起来更具同步性.每个请求IO的功能都具有function (... parameters ..., callback)之类的签名,并且需要给其提供一个回调,该回调将在请求的操作完成时被调用(请注意,大部分时间都在等待OS发出完成信号-时间可以用来做其他工作). Javascript对闭包的支持使您可以使用在回调主体内部的外部(调用)函数中定义的变量-这样可以保留节点运行时将独立调用的不同函数之间的状态.另请参见继续传递样式.此外,在调用函数产生了IO操作后,调用函数通常会return控制节点的事件循环.该循环将调用计划执行的下一个回调或函数(很可能是由于操作系统通知了相应的事件),这将允许并发处理多个请求.您可以将节点的事件循环视为与内核的调度程序类似:内核将在其未完成的IO完成后调度执行阻塞线程,而节点将在相应事件发生时调度回调已经发生了.高度并发,没有并行性最后,短语除了代码之外的所有事物并行运行"在捕捉节点允许您的代码通过单个线程处理来自数十万个开放套接字的请求这一点上做得很出色通过在单个执行流中对所有js逻辑进行多路复用和排序来同时进行(尽管在此处说一切并行运行"可能不正确-参见并发与并行性-有什么区别?).这对于webapp服务器非常有效,因为实际上大部分时间都花在等待网络或磁盘(数据库/套接字)上,并且逻辑并不占用大量CPU,也就是说:这对于IO绑定非常有效工作量.I'm not a Node programmer, but I'm interested in how the single threaded non blocking IO model works.After I read the article understanding-the-node-js-event-loop, I'm really confused about it.It gave an example for the model: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(); });Que: When there are two request A(comes first) and B since there is only a single thread, the server-side program will handle the request A firstly: doing SQL querying is asleep statement standing for I/O wait. And The program is stucked at the I/O waiting, and cannot execute the code which renders the web page behind. Will the program switch to request B during the waiting? In my opinion, because of the single thread model, there is no way to switch one request from another. But the title of the example code says that everything runs in parallel except your code. 解决方案 Node.js is built upon libuv, a cross-platform library that abstracts apis/syscalls for asynchronous (non-blocking) input/output provided by the supported OSes (Unix, OS X and Windows at least).Asynchronous IOIn this programming model open/read/write operation on devices and resources (sockets, filesystem, etc.) managed by the file-system don't block the calling thread (as in the typical synchronous c-like model) and just mark the process (in kernel/OS level data structure) to be notified when new data or events are available. In case of a web-server-like app, the process is then responsible to figure out which request/context the notified event belongs to and proceed processing the request from there. Note that this will necessarily mean you'll be on a different stack frame from the one that originated the request to the OS as the latter had to yield to a process' dispatcher in order for a single threaded process to handle new events.The problem with the model I described is that it's not familiar and hard to reason about for the programmer as it's non-sequential in nature. "You need to make request in function A and handle the result in a different function where your locals from A are usually not available."Node's model (Continuation Passing Style and Event Loop)Node tackles the problem leveraging javascript's language features to make this model a little more synchronous-looking by inducing the programmer to employ a certain programming style. Every function that requests IO has a signature like function (... parameters ..., callback) and needs to be given a callback that will be invoked when the requested operation is completed (keep in mind that most of the time is spent waiting for the OS to signal the completion - time that can be spent doing other work). Javascript's support for closures allows you to use variables you've defined in the outer (calling) function inside the body of the callback - this allows to keep state between different functions that will be invoked by the node runtime independently. See also Continuation Passing Style.Moreover, after invoking a function spawning an IO operation the calling function will usually return control to node's event loop. This loop will invoke the next callback or function that was scheduled for execution (most likely because the corresponding event was notified by the OS) - this allows the concurrent processing of multiple requests.You can think of node's event loop as somewhat similar to the kernel's dispatcher: the kernel would schedule for execution a blocked thread once its pending IO is completed while node will schedule a callback when the corresponding event has occured.Highly concurrent, no parallelismAs a final remark, the phrase "everything runs in parallel except your code" does a decent job of capturing the point that node allows your code to handle requests from hundreds of thousands open socket with a single thread concurrently by multiplexing and sequencing all your js logic in a single stream of execution (even though saying "everything runs in parallel" is probably not correct here - see Concurrency vs Parallelism - What is the difference?). This works pretty well for webapp servers as most of the time is actually spent on waiting for network or disk (database / sockets) and the logic is not really CPU intensive - that is to say: this works well for IO-bound workloads. 这篇关于单线程无阻塞IO模型在Node.js中的工作方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-20 02:09