当作为类的方法调用时,如何以多线程方式多次运行单个方法?
起初我尝试使用cluster
模块,但我意识到它只是从头开始重新运行整个流程,这是正确的。
我怎样才能实现下面概述的目标?
我希望一个类的方法能够生成 n 个进程,并且当并行任务完成时,我可以解析该方法返回的 promise 。
下面代码的问题是调用 cluster.fork()
会 fork index.js
进程。
index.js
const Person = require('./Person.js');
var Mary = new Person('Mary');
Mary.run(5).then(() => {...});
console.log('I should only run once, but I am called 5 times too many');
Person.js
const cluster = require('cluster');
class Person{
run(distance){
var completed = 0;
return new Promise((resolve, reject) => {
for(var i = 0; i < distance; i++) {
// run a separate process for each
cluster.fork().send(i).on('message', message => {
if (message === 'completed') { ++completed; }
if (completed === distance) { resolve(); }
});
}
});
}
}
最佳答案
我认为简短的回答是不可能的。更糟糕的是——这与 js 无关。对于特定问题中的多(进程或线程),您基本上需要每个线程中的对象副本,因为它需要(可能)访问字段 - 在这种情况下,您需要在每个线程中初始化它或共享内存。我认为集群
中没有提供最后一个,并且在其他语言的每个用例中都不是微不足道的。
如果计算独立于 Person,我建议您提取它,并使用通常的(在 index.js
中):
if(cluster.isWorker) {
//Use the i for calculation
} else {
//Create Person, then fork children in for loop
}
然后,您收集结果并根据需要更改人员。您将复制 index.js
,但这是标准的,您只运行您需要的内容。
问题是结果是否取决于人。如果这些对于所有i
都是恒定的,您仍然可以将它们独立地发送到您的 fork 。否则你所拥有的就是 fork 的唯一方法。一般来说,集群中的 fork 并不是针对方法,而是针对应用程序本身,这是标准的 fork 行为。
另一种解决方案
根据您的评论,我建议您查看child_process.execFile或同一文件上的 child_process.exec
。
这样您就可以动态生成一个完全独立的进程。现在,您不再调用 cluster.fork,而是调用 execFile。您可以使用退出代码或 stdout 作为返回值(stderr 等)。 Promise 现在替换为:
var results = []
for(var i = 0; i < distance; i++) {
// run a separate process for each
results.push(child_process.execFile().child.execFile('node', 'mymethod.js`,i]));
}
//... catch the exit event from all results or return a callback using results.
在 mymethod.js
中,让您的代码接受 i
并在退出代码中或通过 stdout 返回您想要的内容,这两个属性都是返回的 child_process 的属性
。这有点 un-node.js
-y,因为您正在等待异步调用,但您的要求是非标准的。因为我不确定你如何使用它,也许用数组返回回调是一个更好的主意。
关于Node.js 在类方法中生成多个线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46978955/