process
对象感知和控制NodeJS自身进程的方方面面。另外需要注意的是,process
不是内置模块,而是一个全局对象,因此在任何地方都可以直接使用。child_process
模块可以创建和控制子进程。该模块提供的API中最核心的是.spawn
,其余API都是针对特定使用场景对它的进一步封装,算是一种语法糖。cluster
模块是对child_process
模块的进一步封装,专用于解决单进程NodeJS Web服务器无法充分利用多核CPU的问题。function main(argv) {
// ...
}
main(process.argv.slice(2));
try {
// ...
} catch (err) {
// ...
process.exit(1);
}
process.stdin
、process.stdout
和process.stderr
,function log() {
process.stdout.write(
util.format.apply(util, arguments) + '\n');
}
http.createServer(callback).listen(80, function () {
var env = process.env,
uid = parseInt(env['SUDO_UID'] || process.getuid(), 10),
gid = parseInt(env['SUDO_GID'] || process.getgid(), 10);
process.setgid(gid);
process.setuid(uid);
});
sudo
获取root
权限的,运行程序的用户的UID
和GID
保存在环境变量SUDO_UID
和SUDO_GID
里边。如果是通过chmod +s
方式获取root
权限的,运行程序的用户的UID
和GID
可直接通过process.getuid
和process.getgid
方法获取;process.setuid
和process.setgid
方法只接受number类型的参数。
降权时必须先降GID
再降UID
,否则顺序反过来的话就没权限更改程序的GID
了。
var child = child_process.spawn('node', [ 'xxx.js' ]);
child.stdout.on('data', function (data) {
console.log('stdout: ' + data);
});
child.stderr.on('data', function (data) {
console.log('stderr: ' + data);
});
child.on('close', function (code) {
console.log('child process exited with code ' + code);
});
使用了.spawn(exec, args, options)
方法,该方法支持三个参数。
上例中虽然通过子进程对象的.stdout
和.stderr
访问子进程的输出,但通过options.stdio
字段的不同配置,可以将子进程的输入输出重定向到任何数据流上,或者让子进程共享父进程的标准输入输出流,或者直接忽略子进程的输入输出。
/* parent.js */
var child = child_process.spawn('node', [ 'child.js' ]);
child.kill('SIGTERM');
/* child.js */
process.on('SIGTERM', function () {
cleanUp();
process.exit(0);
});
.kill
方法向子进程发送SIGTERM信号,子进程监听process
对象的SIGTERM事件响应信号。/* parent.js */
var child = child_process.spawn('node', [ 'child.js' ], {
stdio: [ 0, 1, 2, 'ipc' ]
});
child.on('message', function (msg) {
console.log(msg);
});
child.send({ hello: 'hello' });
/* child.js */
process.on('message', function (msg) {
msg.hello = msg.hello.toUpperCase();
process.send(msg);
});
options.stdio
字段中通过ipc开启了一条IPC通道,之后就可以监听子进程对象的message
事件接收来自子进程的消息,并通过.send
方法给子进程发送消息。process
对象上监听message
事件接收来自父进程的消息,并通过.send
方法向父进程发送消息。数据在传递过程中,会先在发送端使用JSON.stringify
方法序列化,再在接收端使用JSON.parse
方法反序列化。/* daemon.js */
function spawn(mainModule) {
var worker = child_process.spawn('node', [ mainModule ]);
worker.on('exit', function (code) {
if (code !== 0) {
spawn(mainModule);
}
});
}
spawn('worker.js');