Javascript(node.js)限制了子进程的数量

时间:2015-06-02 12:49:30

标签: javascript node.js max child-process

希望我可以清楚地描述我正在寻找的东西。使用Node和Python。

我尝试并行运行多个子进程(.py脚本,使用child_process.exec()),但一次不超过指定的数量(例如,2)。我批量收到未知数​​量的请求(比如这批请求有3个请求)。我想停止产生过程,直到当前的过程结束。

for (var i = 0; i < requests.length; i++) {

    //code that would ideally block execution for a moment
    while (active_pids.length == max_threads){
        console.log("Waiting for more threads...");
        sleep(100)
        continue
    };

    //code that needs to run if threads are available
    active_pids.push(i);

    cp.exec('python python-test.py '+ requests[i],function(err, stdout){
        console.log("Data processed for: " + stdout);

        active_pids.shift();

          if (err != null){
              console.log(err);
          }
    });
}

我知道虽然循环不起作用,但这是第一次尝试。

我猜这是用

做到这一点的方法
setTimeout(someSpawningFunction(){

    if (active_pids.length == max_threads){
        return
    } else {
        //spawn process?
    }

},100)

但我无法完全理解它。

或者

waitpid(-1)

在if语句中插入for循环代替while循环?但是我现在无法安装waitpid()模块。

是的,我知道阻止执行在JS中被认为非常糟糕,但就我而言,我需要它发生。如果可能的话,我宁愿避免使用外部集群管理器类型库。

感谢您的帮助。

编辑/部分解决方案

丑陋的黑客将使用以下答案:this SO question(execSync())。但这会阻止循环直到最后一个孩子完成。这是我迄今为止的计划,但并不理想。

2 个答案:

答案 0 :(得分:4)

来自async库的

async.timesLimit是此处使用的完美工具。它允许您异步运行函数n次,但在任何给定时间并行运行最多k个函数调用。

async.timesLimit(requests.length, max_threads, function(i, next){
    cp.exec('python python-test.py '+ requests[i], function(err, stdout){
        console.log("Data processed for: " + stdout);

        if (err != null){
            console.log(err);
        }

        // this task is resolved
        next(null, stdout);
    });
}, function(err, stdoutArray) {
  // this runs after all processes have run; what's next?
});

或者,如果您希望错误致命并停止循环,请致电next(err, stdout)

答案 1 :(得分:2)

您可以只维护一个等待运行的外部进程队列,以及一个当前正在运行的计数器的计数器。队列只包含每个进程的对象,该对象具有包含您需要知道要运行的进程所需的数据的属性。您可以将这些对象的数组用于队列。

每当您收到运行外部流程的新请求时,您都会将其添加到队列中,然后启动外部流程,每次启动计数器时都会增加计数器,直到您的计数器达到最大值。

然后,在监视这些外部进程时,无论何时完成,您都会递减计数器,如果等待运行的任务队列不为空,则启动另一个并再次增加计数器。

async库内置了这种类型的功能(一次运行特定数量的操作),尽管使用队列和计数器实现自己并不困难。关键是你只需要为你的外部流程挂钩即可,这样你就可以维护计数器并启动任何等待的新任务。

没有理由需要使用同步或串行执行或阻止才能在此实现目标。