我不是Node程序员,但我对单线程非阻塞IO模型如何工作感兴趣。
在我阅读了理解node-js-event-loop这篇文章之后,我真的很困惑。
文中给出了模型的一个例子:
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 requests 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 stuck 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。)在等待过程中,节点如何将A切换到B ?并且可以
你解释了Node的单线程非阻塞IO模型
简单的方法吗?如果你能帮助我,我会很感激的。:)
好的,到目前为止,大部分事情应该都清楚了……棘手的部分是SQL:如果它实际上不是在另一个线程或进程中运行,SQL的执行必须被分解成单独的步骤(由一个为异步执行而设计的SQL处理器!),其中执行非阻塞的步骤,而阻塞的步骤(例如睡眠)实际上可以传输到内核(作为警报中断/事件),并放在主循环的事件列表中。
这意味着,例如,SQL的解释,等等是立即完成的,但在等待期间(存储为一个事件,将来由内核在一些kqueue, epoll,…结构;与其他IO操作一起),主循环可以做其他事情,并最终检查这些IOs是否发生了什么并等待。
所以,换句话说:程序永远不会(被允许)卡住,休眠调用永远不会被执行。它们的职责是由内核(写一些东西,等待一些东西通过网络,等待时间流逝)或另一个线程或进程完成的。- Node进程检查在每个事件循环周期中,内核是否在唯一的阻塞调用中完成了至少一项任务。当所有非阻塞的事情都完成时,就达到了这一点。
清楚了吗?: -)
我不知道Node。但是c.query是从哪里来的呢?
Node.js基于事件循环编程模型。事件循环在单个线程中运行,反复等待事件,然后运行订阅这些事件的任何事件处理程序。例如,事件可以是
计时器等待完成
下一个数据块已经准备好写入该文件
有一个新的HTTP请求即将到来
所有这些都在单个线程中运行,没有JavaScript代码是并行执行的。只要这些事件处理程序很小,并且等待更多的事件本身,一切都能很好地工作。这允许单个Node.js进程并发处理多个请求。
(在事件起源的地方有一点魔力。其中一些涉及并行运行的低级工作线程。)
在这个SQL案例中,在进行数据库查询和在回调中获得结果之间发生了很多事情(事件)。在此期间,事件循环不断向应用程序注入生命,并一次一个小事件推进其他请求。因此,并发地服务多个请求。
根据:“来自10,000英尺的事件循环- Node.js背后的核心概念”。
好的,到目前为止,大部分事情应该都清楚了……棘手的部分是SQL:如果它实际上不是在另一个线程或进程中运行,SQL的执行必须被分解成单独的步骤(由一个为异步执行而设计的SQL处理器!),其中执行非阻塞的步骤,而阻塞的步骤(例如睡眠)实际上可以传输到内核(作为警报中断/事件),并放在主循环的事件列表中。
这意味着,例如,SQL的解释,等等是立即完成的,但在等待期间(存储为一个事件,将来由内核在一些kqueue, epoll,…结构;与其他IO操作一起),主循环可以做其他事情,并最终检查这些IOs是否发生了什么并等待。
所以,换句话说:程序永远不会(被允许)卡住,休眠调用永远不会被执行。它们的职责是由内核(写一些东西,等待一些东西通过网络,等待时间流逝)或另一个线程或进程完成的。- Node进程检查在每个事件循环周期中,内核是否在唯一的阻塞调用中完成了至少一项任务。当所有非阻塞的事情都完成时,就达到了这一点。
清楚了吗?: -)
我不知道Node。但是c.query是从哪里来的呢?
函数c.query()有两个参数
c.query("Fetch Data", "Post-Processing of Data")
在这种情况下,“获取数据”操作是一个DB-Query,现在这可能由Node.js通过衍生出一个工作线程来处理,并赋予它执行DB-Query的任务。(记住Node.js可以在内部创建线程)。这使得函数能够立即返回,没有任何延迟
第二个参数“Post-Processing of Data”是一个回调函数,节点框架注册这个回调函数,并由事件循环调用。
因此,语句c.query (paramenter1, parameter2)将立即返回,使node能够满足另一个请求。
附注:我刚刚开始理解节点,实际上我想把这作为对@Philip的评论,但由于没有足够的声誉点,所以把它作为答案写了下来。