Return 来自 Node.js 中多线程进程的值
Return value from multithreaded process in Node.js
我设计了一个函数 diversify()
来获取一些昂贵的函数 f()
和 运行 它在机器的所有内核上并行运行 运行 .我还对此进行了设置,以便如果 f()
return 在一个核心上有一个值,则所有其他线程都会自动终止。代码如下:
let diversify = f => {
// Split a function `f` into a thread for each core of the machine.
// The first thread to finish will return its result and end all others.
if ( cluster.isMaster ) {
let children = []
for ( let i = 0; i < os.cpus().length; i++) {
children.push(cluster.fork())
}
cluster.on('message', (_, msg) => {
if ( msg.cmd == 'stop' ) { children.forEach(child => {
child.process.kill()
})}
return msg.out
})
} else {
let out = f()
process.send({ cmd: 'stop', out })
}
}
问题是在一个进程通过msg.cmd = 'stop'
告诉主进程停止后,没有办法return输出msg.out
。它在上面的代码中实现的方式是,return msg.out
语句位于嵌套在较大的 diversify 函数中的匿名函数中。因此,当您 运行 类似于 diversify(() => { return true })
时,此 return 值不会公开,从而导致 undefined
。有什么方法可以 return msg.out
中发送的内容吗?
向工作人员发送消息是异步设计的。
技术上无法 return
来自作为事件处理程序的回调的值,因为事件可能随时发生。
此问题的规范解决方案是 promises。只需将函数体包装在一个 promise 和 resolve
值中而不是返回它。
const diversify = (f) =>
new Promise((resolve) => {
// Split a function `f` into a thread for each core of the machine.
// The first thread to finish will return its result and end all others.
if (cluster.isMaster) {
let children = [];
for (let i = 0; i < os.cpus().length; i++) {
children.push(cluster.fork());
}
cluster.on('message', (_, msg) => {
if (msg.cmd == 'stop') {
children.forEach((child) => {
child.process.kill();
});
}
resolve(msg.out);
});
} else {
let out = f();
process.send({ cmd: 'stop', out });
}
});
然后可以在 out
:
中访问结果
const getPid = () => {
return process.pid;
};
diversify(() => {
console.log(getPid());
return true;
}).then((out) => {
console.log(out); // true
});
// or using async/await
const diversifyAsync = async () => {
const out = await diversify(() => {
console.log(getPid());
return true;
});
console.log(out); // true
};
diversifyAsync();
我设计了一个函数 diversify()
来获取一些昂贵的函数 f()
和 运行 它在机器的所有内核上并行运行 运行 .我还对此进行了设置,以便如果 f()
return 在一个核心上有一个值,则所有其他线程都会自动终止。代码如下:
let diversify = f => {
// Split a function `f` into a thread for each core of the machine.
// The first thread to finish will return its result and end all others.
if ( cluster.isMaster ) {
let children = []
for ( let i = 0; i < os.cpus().length; i++) {
children.push(cluster.fork())
}
cluster.on('message', (_, msg) => {
if ( msg.cmd == 'stop' ) { children.forEach(child => {
child.process.kill()
})}
return msg.out
})
} else {
let out = f()
process.send({ cmd: 'stop', out })
}
}
问题是在一个进程通过msg.cmd = 'stop'
告诉主进程停止后,没有办法return输出msg.out
。它在上面的代码中实现的方式是,return msg.out
语句位于嵌套在较大的 diversify 函数中的匿名函数中。因此,当您 运行 类似于 diversify(() => { return true })
时,此 return 值不会公开,从而导致 undefined
。有什么方法可以 return msg.out
中发送的内容吗?
向工作人员发送消息是异步设计的。
技术上无法 return
来自作为事件处理程序的回调的值,因为事件可能随时发生。
此问题的规范解决方案是 promises。只需将函数体包装在一个 promise 和 resolve
值中而不是返回它。
const diversify = (f) =>
new Promise((resolve) => {
// Split a function `f` into a thread for each core of the machine.
// The first thread to finish will return its result and end all others.
if (cluster.isMaster) {
let children = [];
for (let i = 0; i < os.cpus().length; i++) {
children.push(cluster.fork());
}
cluster.on('message', (_, msg) => {
if (msg.cmd == 'stop') {
children.forEach((child) => {
child.process.kill();
});
}
resolve(msg.out);
});
} else {
let out = f();
process.send({ cmd: 'stop', out });
}
});
然后可以在 out
:
const getPid = () => {
return process.pid;
};
diversify(() => {
console.log(getPid());
return true;
}).then((out) => {
console.log(out); // true
});
// or using async/await
const diversifyAsync = async () => {
const out = await diversify(() => {
console.log(getPid());
return true;
});
console.log(out); // true
};
diversifyAsync();