Node.js 多进程

Node.js 多进程

参考https://www.runoob.com/nodejs/nodejs-process.html

  • Node.js是单线程的模式运行的,但是使用事件驱动型来处理并发,所以在多核CPU上创建多个子进程来提高性能;
  • 每个子进程带三个流对象:child.stdinchild.stdoutchild.stderr
  • 子进程的三个对象可能会共享父进程的stdio流,或是共享独立的被导流的流对象。

Node.js提供了child_process模块来创建子进程:

  • child_process.exec():使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回;
  • child_process.spawn():使用指定的命令行参数创建子进程;
  • child_process.fork():是child_process.spawn()的特殊形式,使用子进程运行脚本或命令。
    fork('./son.js')相当于spawn('node', ['./son.js'])。与spawn方法不同的是,fork会在父子进程之间建立一个通信管道,用于进程之间的通信。

exec()方法

使用子进程执行命令,缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回。

语法

  child_process.exec(command[, options], callback)
  • command:字符串,将要运行的命令,参数以空格隔开;
  • options:对象,可以是:
  1. cwd,字符串,子进程的当前工作目录(Current Working Directory);
  2. env,对象,环境变量键值对(Environment key-value)
  3. encoding,字符串,字符编码(默认'utf8')
  4. shell,字符串,将要执行的命令的shell(Linux中默认为bash shell,Windows中默认为cmd);
  5. timeout,数字,超时时间(默认为0,立即执行);
  6. maxBuffer,数字,子进程中允许存在的最大缓冲,超出此值子进程将被杀死;
  7. killSignal,字符串,结束信号(默认'SIGTERM');
  8. uid,数字,设置用户进程的ID;
  9. gid,数字,设置进程组的ID。
  • callback:回调函数,包含三个参数err, stdout和stderr;

返回值

exec()方法返回最大的缓冲区的内容,并等待进程结束,一次性返回缓冲区的内容。
创建两个文件support.js和master.js:
support.js:

  console.log("进程 "+process.argv[2]+"执行");

master.js:

const fs = require('fs');
const child_process = require('child_process');

for(let i=0;i<3;i++){
	let workerProcess = child_process.exec('node support.js '+i, (err, stdout, stderr)=>{
		if(err){
			console.log(err.stack);
			console.log('Error code: '+err.code);
			console.log('Signal received: '+err.signal);
		}
		console.log('stdout: '+stdout);
		console.log('stderr: '+stderr);
	});
	
	workerProcess.on('exit', (code)=>{
		console.log('子进程已退出,退出码:'+code);
	});
}

执行master.js,结果:

spawn()方法

child_process.spawn()使用指定的命令行参数来创建子进程。

语法

  child_process.spawn(command[, args][, options])
  • command:字符串,将要运行的命令;
  • args:字符串参数数组,['arg1', 'arg2', ...]
  • options:对象,可以是:
  1. cwd,字符串,子进程的当前工作目录(Current Working Directory);
  2. env,对象,环境变量键值对(Environment key-value);
  3. stdio,字符串数组,子进程的stdio配置;
  4. detached,布尔,是否子进程作为进程组的领导;
  5. uid,数字,设置用户进程的ID;
  6. gid,数字,设置进程组的ID。

返回值

spawn()方法返回ChildProcess对象,在进程返回大量数据时使用。进程一旦开始执行时,spawn()就开始接收响应。
还是master.js和support.js,
support.js:

  console.log("进程 "+process.argv[2]+"执行");

master.js:

const fs = require('fs');
const child_process = require('child_process');

for(let i=0;i<3;i++){
	//此处i可能会被转为string类型
	let workerProcess = child_process.spawn('node', ['support.js', i]);
	
	workerProcess.stdout.on('data', (data)=>{
		console.log('stdout: '+data);
	});
	
	workerProcess.stderr.on('data', (data)=>{
		console.log('stderr: '+data);
	});
	
	workerProcess.on('close', (code)=>{
		console.log('子进程已退出,退出码:'+code);
	});
}

结果:

fork()方法

child.process.fork()时spawn()方法的特殊形式,用于创建进程。与spawn方法不同的是,fork会在父子进程之间建立一个通信管道,用于进程之间的通信。

语法

  child_process.fork(modulePath[, args][, options])
  • modulePath:字符串,将要在子进程中运行的脚本;
  • args:字符串数组,参数;
  • options**:对象,可以是:
  1. cwd,字符串,子进程的当前工作目录(Current Working Directory);
  2. env,对象,环境变量键值对(Environment key-value);
  3. execPath,字符串,用于创建子进程的可执行文件;
  4. execArgv,字符串数组,execPath的参数;
  5. silent,布尔,是否将子进程的三个流对象关联至父进程,否则从父进程中继承(默认为false);
  6. uid,数字,设置用户进程的ID;
  7. gid,数字,设置进程组的ID

返回值

返回ChildProcess对象 ,比spawn()方法返回的实例还多一个内建的通信通道。
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);
     });
  }

结果:

原文地址:https://www.cnblogs.com/pangqianjin/p/14210574.html