【发布时间】:2020-02-27 08:29:52
【问题描述】:
所以我正在执行这段代码来检查 libuv 库创建的线程池中的线程数 -
var fs = require('fs');
var util = require('util');
var sleep = require('sleep');
var start = process.hrtime();
var sample_func = function(callback) {
var i = 0;
sleep.sleep(1);
callback();
}
for (var i = 0; i < 6; ++i) {
(function (id) {
sample_func(function () {
var end = process.hrtime(start);
console.log(util.format('sample func %d finished in %ds', id, end[0] + end[1] / 1e9));
});
})(i);
}
由于 libuv 默认在线程池中创建 4 个线程,并且我的示例函数是异步的,因此我希望在我的控制台中打印此输出 -
sample func 0 finished in 1.003170344s
sample func 1 finished in 1.052704191s
sample func 2 finished in 1.058100525s
sample func 3 finished in 1.060514229s
sample func 4 finished in 2.003446385s
sample func 5 finished in 2.007682862s
所以前 4 次迭代并行运行,最后 2 次必须等待前 4 次完成。然而我得到的是这个 -
sample func 0 finished in 1.00095422s
sample func 1 finished in 2.056155718s
sample func 2 finished in 3.058480649s
sample func 3 finished in 4.061336076s
sample func 4 finished in 5.063556904s
sample func 5 finished in 6.066219487s
这意味着每次迭代都会一个接一个地执行,总共需要 6 秒。任何人都可以在这里帮助我为什么会发生这种情况?
PS:我打印了 process.env.UV_THREADPOOL_SIZE 值,我得到了 undefined;节点版本:v12.9.1
谢谢
【问题讨论】:
-
sleep在每次迭代中同步阻塞一秒钟。不确定 libuv,您将不得不以其他方式调用并行处理(child_process?) -
Node.js 只使用一个线程来执行代码。它对网络 I/O 使用相同的单线程(不是单独的线程)。它只旋转额外的线程来处理磁盘 I/O、DNS(通常没有非阻塞 API)和一些加密函数(因为它是计算,而不是 I/O)。浏览器中的 Node.js 和 javascript 本质上是单线程的。它是异步/事件/非阻塞的,但是是单线程的(你会发现在其他语言中非阻塞代码往往是单线程的)。它可以并行等待,但可以串行执行计算
-
据我了解,所有的异步函数都由线程池中的线程执行,然后回调进入任务队列,被事件循环一一拾取在main中执行线。如果我错了,请纠正我。
标签: node.js asynchronous libuv