我对node.js中libuv threadpool的理解是否正确?

时间:2016-05-21 17:11:27

标签: node.js threadpool libuv

我编写了以下node.js程序(Ubuntu 14.04上的节点版本6.2.0),以了解有关node.js中libuv threadpool的更多信息。在程序中,我正在阅读两个大小为10KB的文本文件。成功读取文件后,我正在做一些计算密集型任务(在回调中)。

var log4js = require('log4js');// For logging output with timestamp
var logger = log4js.getLogger();

var fs=require('fs');

fs.readFile('testFile0.txt',function(err,data){//read testFile0.txt
logger.debug('data read of testFile0.txt');

for(var i=0; i<10000; i++)//Computing intensive task. Looping for 10^10 times
{
    for(var j=0; j<10000; j++)
    {
        for(var k=0; k<100; k++)
        {

        }
    }
}
});

fs.readFile('testFile1.txt',function(err,data){//read testFile1.txt
logger.debug('data read of testFile1.txt');

for(var i=0; i<10000; i++)//Computing intensive task. Looping for 10^10 times
{
    for(var j=0; j<10000; j++)
    {
        for(var k=0; k<100; k++)
        {

        }
    }
}
});

根据我对libuv线程池的理解,应立即读取这两个文件,并打印语句&#34;读取testFile0.txt&#34;,#34;读取testFile1的数据之间的时间差。 TXT&#34;因为默认线程池大小为4并且只有两个异步请求(文件读取操作),所以应该非常少(以毫秒或最多为单位)。但是,语句的打印时间差异&#34; testFile0.txt&#34; && 34; testFile0.txt&#34;的数据读取相当大(10秒)。有人可以解释为什么时差如此之大?在回调中完成的计算密集型任务是否会导致较大的时间差?

1 个答案:

答案 0 :(得分:2)

libuv有一个大小为4的线程池(默认情况下),因此该部分是正确的。现在,让我们看看它是如何实际使用的。

当某个操作在线程池中排队时,它会在其中一个线程上运行,然后将结果发布到&#34; main&#34;线程,它是循环运行的线程。结果以FIFO样式处理。

在您的情况下,读取文件并行发生,但处理结果将被序列化。这意味着虽然并行地从磁盘读取字节,但回调将始终一个接一个地运行。

你看到了延迟,因为第二个回调只能在第一个回调完成后运行,但需要大约10秒,因此延迟。

使这个完全平行的一种方法是在线程池本身进行计算,尽管你需要一个使用uv_queue_work或使用child_process mdoule的插件。 / p>