gpt4 book ai didi

javascript - 将大数组传递给 Node 子进程

转载 作者:IT老高 更新时间:2023-10-28 13:04:09 26 4
gpt4 key购买 nike

我想要在大型阵列上执行复杂的 CPU 密集型工作。理想情况下,我想将此传递给子进程。

var spawn = require('child_process').spawn;

// dataAsNumbers is a large 2D array
var child = spawn(process.execPath, ['/child_process_scripts/getStatistics', dataAsNumbers]);

child.stdout.on('data', function(data){
console.log('from child: ', data.toString());
});

但是当我这样做时, Node 会给出错误:

spawn E2BIG

我遇到了this article

因此,将数据管道传输到子进程似乎是要走的路。我的代码现在是:

var spawn = require('child_process').spawn;

console.log('creating child........................');

var options = { stdio: [null, null, null, 'pipe'] };
var args = [ '/getStatistics' ];
var child = spawn(process.execPath, args, options);

var pipe = child.stdio[3];

pipe.write(Buffer('awesome'));

child.stdout.on('data', function(data){
console.log('from child: ', data.toString());
});

然后在 getStatistics.js 中:

console.log('im inside child');

process.stdin.on('data', function(data) {
console.log('data is ', data);
process.exit(0);
});

但是没有达到 process.stdin.on 中的回调。如何在我的子脚本中接收流?

编辑

我不得不放弃缓冲方法。现在我将数组作为消息发送:

var cp = require('child_process');
var child = cp.fork('/getStatistics.js');

child.send({
dataAsNumbers: dataAsNumbers
});

但这只有在 dataAsNumbers 的长度低于 20,000 左右时才有效,否则会超时。

最佳答案

拥有如此大量的数据,我会考虑使用 shared memory而不是将数据复制到子进程中(这是使用管道或传递消息时发生的情况)。这将节省内存,减少父进程的 CPU 时间,并且不太可能遇到一些限制。

shm-typed-array是一个非常简单的模块,似乎适合您的应用程序。示例:

parent.js

"use strict";

const shm = require('shm-typed-array');
const fork = require('child_process').fork;

// Create shared memory
const SIZE = 20000000;
const data = shm.create(SIZE, 'Float64Array');

// Fill with dummy data
Array.prototype.fill.call(data, 1);

// Spawn child, set up communication, and give shared memory
const child = fork("child.js");
child.on('message', sum => {
console.log(`Got answer: ${sum}`);

// Demo only; ideally you'd re-use the same child
child.kill();
});
child.send(data.key);

child.js

"use strict";

const shm = require('shm-typed-array');

process.on('message', key => {
// Get access to shared memory
const data = shm.get(key, 'Float64Array');

// Perform processing
const sum = Array.prototype.reduce.call(data, (a, b) => a + b, 0);

// Return processed data
process.send(sum);
});

请注意,我们只是通过 IPC 从父进程向子进程发送一个小“ key ”,而不是整个数据。因此,我们节省了大量的内存和时间。

当然,您可以将 'Float64Array'(例如 double)更改为 typed array您的应用程序需要。请注意,这个库特别只处理一维类型数组;但这应该只是一个小障碍。

关于javascript - 将大数组传递给 Node 子进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44052913/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com