无法调用函数内部的非内置函数

时间:2019-02-16 21:19:17

标签: javascript node.js multithreading parallel-processing

我的代码中有问题-我的代码中有一部分需要进行大量计算(30〜40秒)

我需要尽可能减少这种时间-所以我必须 使用我所有的CPU线程并分配这部分来更快地完成

几天-我对如何在nodejs中编写多线程代码进行了很多研究,并进行了足够的搜索,并且就有关nodejs是单线程还是多线程的方式发表了很多意见,并阅读了一些主题,例如群集,子进程和工作程序..

我更喜欢使用现成的库来避免过多地探讨这些主题, 所以我尝试了这个库https://github.com/Microsoft/napajs,但它引发了我一些问题。

我想要的应该很简单-我只有数组(准备进行并行计算-每个线程都可以在每个元素上工作)  [数据,数据,数据,数据]

我发现这个库:https://www.npmjs.com/package/paralleljs有点简单,并且具有适合我的情况的此方法(映射)

让我们转到我的代码

初始化

var p = new Parallel([54,25,66,23,14,27,15,18] , { maxWorkers : 8 });

3个函数(乐趣是调用export.calc和calcc的主要函数)

exports.calc = function(i,h)
{
    return Math.log2(i*h);
}

function calcc(i,h)
{
    return Math.log2(i*h);
}

function fun(h)
{
    var sum = 0;
   for (var i = 1 ; i < 55555 ; i++)
   {
       for (var l = 1 ; l < 55555 ; l++)
       {
           sum+=(exports.calc(i,l)); // in this case calc is not a function error
           sum+=(calcc(i,l)); // in this case calcc is not defined error
       }
   } 
   return sum;
}

使用地图功能开始并行计算- 此函数应划分数组,并让每个线程分别在每个元素上工作

p.map(fun).then(data => {
        console.log(data);
    });

错误总是很有趣-随时尝试调用非内置函数-例如

Math.max(),String.includes()等等,所有这些内置函数都不会引起任何问题,但是任何非内置函数(例如calcc和export.calc)都会引起问题

根据库文档,它使用子进程-如果这可以帮助实现,

如果您不能解决此问题-但有其他方法可以使此代码成为可能(与任何其他库一起使用)-请共享它

2 个答案:

答案 0 :(得分:1)

这可以通过节点cluster来实现:

var cluster = require('cluster');

function calcc(i,h) {
    return Math.log2(i*h);
}

function fun(h) {
   var sum = 0;
   for (var i = 1 ; i < 5555 ; i++) {
       for (var l = 1 ; l < 5555 ; l++) {
           sum+=(calcc(i,l));
           sum+=(calcc(i,l));
       }
   } 
   return sum;
}

if (cluster.isMaster) {   
  var CPU = 8;    
  var count = 0;

  function messageHandler(msg) {
    console.log(msg);
    count++;
    if (count == CPU)
      console.log('Complete');
  }

  for (let i = 0; i < CPU; i++) {
    var worker = cluster.fork();
    worker.on('message', messageHandler);
  }    
} else if (cluster.isWorker) {
  process.send(fun());
}

由于群集旨在用于网络连接,因此它可以提供一些开销,因此使用child_process.fork()(由cluster使用)的低级实现可能会更有效。

还有针对节点10和更高版本的实验性节点worker threads

答案 1 :(得分:0)

我自己从未使用过并行,但根据行为和使用方式,我认为@estus基本上是正确的。

如果函数本身已传递->它不会带来有关先前环境的任何信息。

您将需要在开始使用的所有功能处进行初始化。

最直接的方法是将其放在主要函数中

function fun(h)
{
    const calc = function(){...}
}

最优雅的是在里面使用require。因此,将您要共享的所有内容放入另一个模块,将其导出,然后执行

function fun(h)
{
    const tools = require('tools');
    tools.calc(...)
}