【问题标题】:Is my understanding of libuv threadpool in node.js correct?我对 node.js 中的 libuv 线程池的理解是否正确?
【发布时间】:2016-05-21 17:11:27
【问题描述】:

我编写了以下 node.js 程序(Ubuntu 14.04 上的节点版本 6.2.0)以了解有关 node.js 中 libuv 线程池的更多信息。在程序中,我正在读取两个大小为 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线程池的理解,应该立即读取这两个文件,并且打印语句“testFile0.txt的数据读取”,“testFile1.txt的数据读取”之间的时间差应该非常小(在毫秒或最多一秒),因为默认线程池大小为 4,并且只有两个异步请求(文件读取操作)。但是,打印语句“testFile0.txt 的数据读取”和“testFile0.txt 的数据读取”之间的时间差相当大(10 秒)。谁能解释一下为什么时差这么大??回调中正在执行的计算密集型任务是否会导致较大的时差?

【问题讨论】:

    标签: node.js threadpool libuv


    【解决方案1】:

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

    当某些操作在线程池中排队时,它会在其中一个线程上运行,然后将结果发布到“主”线程,即循环运行的线程。结果以 FIFO 方式处理。

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

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

    实现真正并行的一种方法是在线程池本身中进行计算,尽管您需要一个插件来使用uv_queue_work 或使用child_process mdoule。

    【讨论】:

      猜你喜欢
      • 2015-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-29
      • 2018-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多