Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js nodej的子进程太多?_Node.js_Child Process - Fatal编程技术网

Node.js nodej的子进程太多?

Node.js nodej的子进程太多?,node.js,child-process,Node.js,Child Process,我使用node递归遍历文件系统,并使用child.exec对每个文件进行系统调用。当在一个小结构上测试时,它工作得很好,只有几个文件夹和文件,但是当在整个主目录上运行时,它会在一段时间后崩溃 child_process.js:945 throw errnoException(process._errno, 'spawn'); ^ Error: spawn Unknown system errno 23 at errnoException (child_process.js:998:1

我使用node递归遍历文件系统,并使用child.exec对每个文件进行系统调用。当在一个小结构上测试时,它工作得很好,只有几个文件夹和文件,但是当在整个主目录上运行时,它会在一段时间后崩溃

child_process.js:945
throw errnoException(process._errno, 'spawn');
      ^
Error: spawn Unknown system errno 23
at errnoException (child_process.js:998:11)
at ChildProcess.spawn (child_process.js:945:11)
at exports.spawn (child_process.js:733:9)
at Object.exports.execFile (child_process.js:617:15)
at exports.exec (child_process.js:588:18)
发生这种情况是因为它耗尽了所有资源吗?我怎样才能避免这种情况

编辑:代码 始终欢迎改进和最佳做法建议:)


问题可能是因为同时有许多打开的文件

考虑使用异步模块来解决这个问题


在当前示例中,您将一次处理20个文件

好,我不知道失败的原因,但是如果这是您期望的(耗尽所有资源)或其他人所说(打开的文件太多),您可以尝试对其使用多任务处理。(fork of Node.JS)提供了这样的功能——它允许在单独的实例中运行任务,但这仍然是在单个进程中完成的

虽然Node.JS应用程序作为一个进程有其局限性——JXcore及其子实例会使这些局限性成倍增加:单个进程即使有一个额外的实例(或者任务,或者我们可以称之为子线程),也会使局限性成倍增加

因此,假设您将在单独的任务中运行每个
spawn()
。或者,由于任务不再在主线程中运行,您甚至可以使用jxcore提供的同步方法:

这几行代码可能是最好的说明:

jxcore.tasks.setThreadCount(4);

var task = function(file) {
  var your_cmd = "do something with " + file;
  return jxcore.utils.cmdSync(your_cmd);
};

jxcore.tasks.addTask(task, "file1.txt", function(ret) {
  console.log("the exit code:", ret.exitCode);
  console.log("output:", ret.out);
});
让我重复一次:任务不会阻塞主线程,因为它正在一个单独的实例中运行


这里记录了多任务API:。

正如在注释中建立的那样,您可能会耗尽文件句柄,因为您在文件上运行了太多并发操作。因此,一个解决方案是限制一次运行的并发操作的数量,以便有太多的文件不能同时使用

这里有一个稍微不同的实现,它使用Bluebird承诺控制操作的异步方面和并发方面

为了简化并发方面的管理,这将首先将整个文件列表收集到一个数组中,然后处理文件名数组,而不是边处理边处理。这使得在Bluebird的
.map()
(在单个数组上工作)中使用内置并发功能变得更容易,因此我们不必自己编写代码:

var Promise = require("bluebird");
var fs = Promise.promisifyAll(require("fs"));
var path = require("path");

// recurse a directory, call a callback on each file (that returns a promise)
// run a max of numConcurrent callbacks at once
// returns a promise for when all work is done
function processDir(dir, numConcurrent, fileCallback) {
    var allFiles = [];

    function listDir(dir, list) {
        var dirs = [];
        return fs.readdirAsync(dir).map(function(file) {
            var filePath = path.join(dir , file);
            return fs.statAsync(filePath).then(function(stats) {
                if (stats.isFile()) {
                    allFiles.push(filePath);
                } else if (stats.isDirectory()) {
                    return listDir(filePath);
                }
            }).catch(function() {
                // ignore errors on .stat - file could just be gone now
                return;
            });
        });
    }

    return listDir(dir, allFiles).then(function() {
        return Promise.map(allFiles, function(filename) {
            return fileCallback(filename);
        }, {concurrency: numConcurrent});
    });
}

// example usage:

// pass the initial directory, 
// the number of concurrent operations allowed at once
// and a callback function (that returns a promise) to process each file
processDir(process.cwd(), 5, function(file) {
    // put your own code here to process each file
    // this is code to cause each callback to take a random amount of time 
    // for testing purposes
    var rand = Math.floor(Math.random() * 500) + 500;
    return Promise.delay(rand).then(function() {
        console.log(file);
    });
}).catch(function(e) {
    // error here
}).finally(function() {
    console.log("done");
});

仅供参考,我认为您会发现,与普通回调方法相比,使用Promissions可以更容易地从许多异步操作中进行正确的错误传播和正确的错误处理。

请发布一个再现错误的最小测试用例。理解正在运行的代码很重要。另外,请阅读模块(它存在的原因等)。此错误是由于打开的文件太多,而不是由于进程太多。如果包含导致问题的实际代码,您总能得到更好的答案。然后可以在特定的上下文中提供答案,包括您正在做的事情以及代码的结构,而不仅仅是提供理论上的答案。由于生成外部进程可以是一个并发操作(可以彼此并发运行),您希望一次运行多少个?您是要序列化(运行一个,等待它完成,然后运行下一个),还是希望一次最多运行N个,其中N是一个选择的数字,以允许一些并行化,但不耗尽系统资源?@jfriend00我希望尽可能多地并行化,所以是的,运行多达N个进程是理想的方法。我使用async.each,但问题是它是一个递归函数,所以限制只适用于每个目录级别。所以,不管怎样,当你深入兔子的深处时,你很可能会超过极限hole@glasspill若它是递归函数,那个么您可以延迟对函数本身的调用,直到处理一些具有每个限制的文件,而不必立即遍历所有深层。所以您可以遍历一个目录,处理文件,然后在他尝试之后再次调用递归函数遍历下一个目录,然后他可能会说这是否解决了问题。
jxcore.tasks.setThreadCount(4);

var task = function(file) {
  var your_cmd = "do something with " + file;
  return jxcore.utils.cmdSync(your_cmd);
};

jxcore.tasks.addTask(task, "file1.txt", function(ret) {
  console.log("the exit code:", ret.exitCode);
  console.log("output:", ret.out);
});
var Promise = require("bluebird");
var fs = Promise.promisifyAll(require("fs"));
var path = require("path");

// recurse a directory, call a callback on each file (that returns a promise)
// run a max of numConcurrent callbacks at once
// returns a promise for when all work is done
function processDir(dir, numConcurrent, fileCallback) {
    var allFiles = [];

    function listDir(dir, list) {
        var dirs = [];
        return fs.readdirAsync(dir).map(function(file) {
            var filePath = path.join(dir , file);
            return fs.statAsync(filePath).then(function(stats) {
                if (stats.isFile()) {
                    allFiles.push(filePath);
                } else if (stats.isDirectory()) {
                    return listDir(filePath);
                }
            }).catch(function() {
                // ignore errors on .stat - file could just be gone now
                return;
            });
        });
    }

    return listDir(dir, allFiles).then(function() {
        return Promise.map(allFiles, function(filename) {
            return fileCallback(filename);
        }, {concurrency: numConcurrent});
    });
}

// example usage:

// pass the initial directory, 
// the number of concurrent operations allowed at once
// and a callback function (that returns a promise) to process each file
processDir(process.cwd(), 5, function(file) {
    // put your own code here to process each file
    // this is code to cause each callback to take a random amount of time 
    // for testing purposes
    var rand = Math.floor(Math.random() * 500) + 500;
    return Promise.delay(rand).then(function() {
        console.log(file);
    });
}).catch(function(e) {
    // error here
}).finally(function() {
    console.log("done");
});