Node.js多进程基础
Node.js
是以单线程的模式运行的,但它使用的是事件驱动来处理并发。这样有助于我们在多核 cpu 的系统上创建多个子进程,从而提高性能。
每个子进程总是带有三个流对象:child.stdin, child.stdout 和child.stderr
。他们可能会共享父进程的 stdio
流,或者也可以是独立的被导流的流对象。
Node
提供了 child_process
模块来创建子进程,方法有:
-
exec
-child_process.exec
使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数的形式返回。 -
spawn
-child_process.spawn
使用指定的命令行参数创建进程。 -
fork
-child_process.fork
是spawn()
的特殊形式,用于在子进程中运行模块,与spawn
方法不同的是,fork
会在父进程与子进程之间,建立一个通信管道,用于进程之间的通信。
1、exec() 方法
child_process.exec(command[, options], callback)
support.py 文件代码:
# -*- coding: utf-8 -*-
import sys
print("进程 " +sys.argv[1] +" 执行。")
master.js 文件代码:
const fs = require('fs');
const child_process = require('child_process');
for(var i=0; i<3; i++) {
//创建三个子进程
var workerProcess = child_process.exec('python support.py '+i, function (error, stdout, stderr) {
if (error) {
console.log(error.stack);
console.log('Error code: '+error.code);
console.log('Signal received: '+error.signal);
}
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
});
workerProcess.on('exit', function (code) {
console.log('子进程已退出,退出码 '+code);
});
}
2、spawn()方法
child_process.spawn(command[, args][, options])
support.py 文件代码:
# -*- coding: utf-8 -*-
import sys
print("进程 " +sys.argv[1] +" 执行。")
master.js 文件代码:
const fs = require('fs');
const child_process = require('child_process');
for(var i=0; i<3; i++) {
var workerProcess = child_process.spawn('python', ['support.py', i]);
workerProcess.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
workerProcess.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
workerProcess.on('close', function (code) {
console.log('子进程已退出,退出码 '+code);
});
}
3、fork()方法
child_process.fork(modulePath[, args][, options])
modulePath: String
,将要在子进程中运行的模块
support.js 文件代码:
console.log("进程 " + process.argv[2] + " 执行。" );
master.js 文件代码:
const fs = require('fs');
const child_process = require('child_process');
for(var i=0; i<3; i++) {
var worker_process = child_process.fork("support.js", [i]);
worker_process.on('close', function (code) {
console.log('子进程已退出,退出码 ' + code);
});
}
node调用python
见上述1、exec()方法和spawn()方法。
比较exec和spawn
1、
exec将子进程输出结果暂放在buffer中
,在结果完全返回后
,再将输出一次性的以回调函数返回
。如果exec的buffer体积设置的不够大,它将会以一个“maxBuffer exceeded”错误失败告终。而spawn在子进程开始执行后
,就不断的将数据从子进程返回给主进程
,它没有回调函数,它通过流的方式
发数据传给主进程,从而实现了多进程之间的数据交换。这个功能的直接用应用场景就是“系统监控”。
2、书写上,exec更方便一些,将整个命令放在第一个参数中,而spqwn需要拆分。
child_process.spawn('python', ['support.py', i])
child_process.exec('python support.py '+i, callback)