process
对象代表应用程序,这是一个全局对象,可以通过它来获取Node.jsy应用程序以及运行该程序的用户、环境等各种信息的属性、方法和事件。/usr/local/bin/node
process.stdin.resume();
process.stdin.on('data',function(chunk){
process.stdout.write(`进程接收到数据: `+chunk);
});
process.argv.forEach((val,index,ary)=> console.log(index,val));
process.memoryUsage()
nextTick方法用于将一个函数推迟到代码中所书写的下一个同步方法执行完毕或异步方法的回调函数开始执行前调用
chdir方法用于修改Node.js应用程序中使用的当前工作目录,使用方式如下
process.chdir(directory);
cwd方法用返回当前目录,不使用任何参数
console.log(process.cwd());
改变当前的工作目录
console.log(`当前目录: ${process.cwd()}`);
process.chdir('..);
console.log(`上层目录: ${process.cwd()});
退出运行Node.js应用程序的进程
process.exit(0);
用于向进程发送一个信号
process.kill(pid,[signal]);
返回当前程序的运行时间
process.uptime()
测试一个代码段的运行时间,返回两个时间,第一个单位是秒,第二个单位是纳秒
let fs = require('fs);
let time = process.hrtime();
let data = fs.readFileSync('index.txt');
let diff = process.hrtime(time);
console.log(`读文件操作耗费的%d秒`,diff[0]);
当运行Node.js应用程序进程退出时触发进程对象的exit事件。可以通过指定事件回调函数来指定进程退出时所执行的处理。
process.on('exit',function(){
console.log('Node.js进程被推出);
});
process.exit();
当应用程序抛出一个未被捕获的异常时触发进程对象的uncaughtException事件
process.on('uncaughtException',function(err){
console.log('捕获到一个未被处理的错误:',err);
});
notExist();
process.stdin.resume();
process.on('SIGINT',function(){
console.log('接收到SIGINT信号');
});
child_process
模块,通过它可以开启多个子进程,在多个子进程之间可以共享内存空间,可以通过子进程的互相通信来实现信息的交换。child_process.spawn(command,[args],[options]);
message
事件默认情况下,子进程的stdin,stdout,stderr导向了ChildProcess这个对象的child.stdin,child.stdout,child.stderr流,
let spawn = require('child_process').spawn;
sapwn('prg',[],{stdio:['pipe','pipe',process.stderr]});
let spawn = require('child_process').spawn;
spawn('prg',[],{stdio:'inherit'});
child.on('close',function(code,signal){});
因为多个进程可能会共享i 个输入/输出,所以当子进程退出时,子进程的输入/输出可能并未终止
child.on('exit',function(code,signal){});
如果子进程开启失败,那么将会触发子进程对象的error事件
child1.on('error', function (err) {
console.log(err);
});
SIGTERM
child.kill([signal]);
let path = require('path');
let {
spawn
} = require('child_process');
//默认情况下,子进程的stdin,stdout,stderr导向了ChildProcess这个对象的child.stdin,child.stdout,child.stderr流,
//这和设置stdio为['pipe', 'pipe', 'pipe']是一样的
let p1 = spawn('node', ['test1.js', 'a'], {
cwd: path.join(__dirname, 'test1')
});
let p2 = spawn('node', ['test3.js'], {
cwd: path.join(__dirname, 'test3'),
stdio: 'pipe'
});
//监听test1.js脚本子进程对象的标准输出的data事件,把数据写给p2
p1.stdout.on('data', function (data) {
console.log('P1:子进程的标准输出:' + data);
p2.stdin.write(data);
});
p1.on('error', function () {
console.log('p1:子进程1开启失败');
});
p2.on('error', function () {
console.log('p2:子进程2开启失败');
});
test1.js
process.stdout.write('p1:子进程当前工作目录为:' + process.cwd() + '\r\n');
process.stdout.write('p1:' + process.argv[2] + ' \r\n');
test2.js
let fs = require('fs');
let path = require('path');
let out = fs.createWriteStream(path.join(__dirname, 'msg.txt'));
process.stdin.on('data', function (data) {
out.write(data);
});
process.stdin.on('end', function () {
process.exit();
});
let cp = require('child_process');
let fs = require('fs');
let path = require('path');
let out = fs.openSync(path.join(__dirname, 'msg.txt'), 'w', 0o666);
let sp = cp.spawn('node', ['4.detached.js'], {
detached: true,
stdio: ['ignore', out, 'ignore']
});
sp.unref();
let count = 10;
let $timer = setInterval(() => {
process.stdout.write(new Date().toString() + '\r\n');
if (--count == 0) {
clearInterval($timer);
}
}, 500);
`
process.exit()
方法显式退出child_process.fork(modulePath,[args],[options]);
child.send(message,[sendHandle]);//在父进程中向子进程发送消息
process.send(message,[sendHandle]);//在子进程中向主进程发送消息
process.on('message',function(m,setHandle){});
当父进程收到子进程发出的消息时,触发子进程的message事件
child.on('message',function(m,setHandle){
//TODO事件回调函数代码
});
5.fork.js
let {
fork
} = require('child_process');
let path = require('path');
let child = fork(path.join(__dirname, 'fork.js'));
child.on('message', function (m) {
console.log('父进程接收到消息:', m);
process.exit();
});
child.send({
name: 'zfpx'
});
child.on('error', function (err) {
console.error(arguments);
});
fork.js
process.on('message', function (m, setHandle) {
console.log('子进程收到消息:', m);
process.send({
age: 9
});
})
在默认情况下子进程对象与父进程对象共享标准输入和标准输出。如果要让子进程对象用独立的标准输入输出,可以将silent属性值设置为 true forkslient.js
let {
fork
} = require('child_process');
let path = require('path');
let p1 = fork('node', [path.join(__dirname, 'fork1.js')], {
silent: true
});
let p2 = fork('node',path.join(__dirname, 'fork2.js'));
p1.stdout.on('data', function (data) {
console.log('子进程1标准输出:' + data);
p2.send(data.toString());
});
p1.on('exit', function (code, signal) {
console.log('子进程退出,退出代码为:' + code);
});
p1.on('error', function (err) {
console.log('子进程开启失败:' + err);
process.exit();
});
fork1.js
process.argv.forEach(function (item) {
process.stdout.write(item + '\r\n');
});
fork2.js
let fs = require('fs');
let out = fs.createWriteStream(path.join(__dirname, 'msg.txt'));
process.on('message', function (data) {
out.write(data);
});
let http = require('http');
let {
fork
} = require('child_process');
let fs = require('fs');
let net = require('net');
let path = require('path');
let child = fork(path.join(__dirname, '8.child.js'));
let server = net.createServer();
server.listen(8080, '127.0.0.1', function () {
child.send('server', server);
console.log('父进程中的服务器已经创建');
let httpServer = http.createServer();
httpServer.on('request', function (req, res) {
if (req.url != '/favicon.ico') {
let sum = 0;
for (let i = 0; i < 100000; i++) {
sum += 1;
}
res.write('客户端请求在父进程中被处理。');
res.end('sum=' + sum);
}
});
httpServer.listen(server);
});
let http = require('http');
process.on('message', function (msg, server) {
if (msg == 'server') {
console.log('子进程中的服务器已经被创建');
let httpServer = http.createServer();
httpServer.on('request', function (req, res) {
if (req.url != '/favicon.ico') {
sum = 0;
for (let i = 0; i < 10000; i++) {
sum += i;
}
res.write('客户端请求在子进程中被处理');
res.end('sum=' + sum);
}
});
httpServer.listen(server);
}
});
let http = require('http');
let options = {
hostname: 'localhost',
port: 8080,
path: '/',
method: 'GET'
}
for (let i = 0; i < 10; i++) {
let req = http.request(options, function (res) {
res.on('data', function (chunk) {
console.log('响应内容:' + chunk);
});
});
req.end();
}
let {
fork
} = require('child_process');
let path = require('path');
let child = fork(path.join(__dirname, '11.socket.js'));
let server = require('net').createServer();
server.on('connection', function (socket) {
if (Date.now() % 2 == 0) {
child.send('socket', socket);
} else {
socket.end('客户端请求被父进程处理!');
}
});
server.listen(41234, );
process.on('message', function (m, socket) {
if (m === 'socket') {
socket.end('客户端请求被子进程处理.');
}
});
let net = require('net');
let client = new net.Socket();
client.setEncoding('utf8');
client.connect(41234, 'localhost');
client.on('data', function (data) {
console.log(data);
});
child_process.exec(command,[options],[callback]);
function(err,stdout,stderr){}
let {
exec
} = require('child_process');
let path = require('path');
let p1 = exec('node test1.js a b c', {
cwd: path.join(__dirname, 'test3')
}, function (err, stdout, stderr) {
if (err) {
console.log('子进程开启失败:' + err);
process.exit();
} else {
console.log('子进程标准输出\r\n' + stdout.toString());
p2.stdin.write(stdout.toString());
}
});
let p2 = exec('node test2.js', {
cwd: path.join(__dirname, 'test3')
}, function (err, stdout, stderr) {
process.exit();
});
let path = require('path');
process.argv.forEach(function (item) {
process.stdout.write(item + '\r\n');
});
let fs = require('fs');
let path = require('path');
let out = fs.createWriteStream(path.join(__dirname, 'msg.txt'));
process.stdin.on('data', function (data) {
out.write(data);
process.exit();
})
execFile
开启一个专门用于运行某个可执行文件的子进程child_process.execFile(file,[args],[optioins],[callback]);
let {
execFile
} = require('child_process');
let path = require('path');
let p1 = execFile('node', ['./test1.js'], {
cwd: path.join(__dirname, 'test4')
}, function (err, stdout, stderr) {
if (err) {
console.log('子进程1开启失败:' + err);
process.exit();
} else {
console.log('子进程标准输出:' + stdout.toString());
p2.stdin.write(stdout.toString());
}
});
let p2 = execFile('node', ['./test2.js'], {
cwd: path.join(__dirname, 'test4')
}, function (err, stdout, stderr) {
if (err) {
console.log('子进程2开启失败:' + err);
process.exit();
} else {
console.log('子进程标准输出:' + stdout.toString());
}
});
#!/usr/bin/env node
let path = require('path');
process.argv.forEach(function (item) {
process.stdout.write(item + '\r\n');
});
#!/usr/bin/env node
let fs = require('fs');
let path = require('path');
let out = fs.createWriteStream(path.join(__dirname, 'msg.txt'));
process.stdin.on('data', function (data) {
out.write(data);
process.exit();
})
为了利用多核CPU的优势,Node.js提供了一个cluster模块允许在多个子进程中运行不同的Node.js应用程序。
cluster.fork([env]);
for(let index in cluster.workers){
console.log(cluster.workers[index]);
}
if(cluster.isMaster){
cluster.fork()
}else if(cluster.isWorker){
console.log('I am worker #'+cluster.worker.id);
}
let cluster = require('cluster');
let http = require('http');
if (cluster.isMaster) {
cluster.fork();
console.log('这段代码运行在主进程里');
} else {
http.createServer(function (req, res) {
if (req.url != '/favicon.ico') {
res.end('hello');
console.log('这段代码运行在子进程里');
}
}).listen(8080);
}
当使用fork方法开启子进程时,将同时触发fork事件
cluster.on('fork',function(worker){
console.log('子进程 '+workder.id+'被开启');
});
cluster.on('online',function(worker){
console.log('已经收到子进程#'+workder.id+"的消息");
});
当在子进程运行的Node.js应用程序中调用服务器的listen方法后,该服务器开始对指定地址及端口进行监听,同时触发listening事件。
let cluster = require('cluster');
let http = require('http');
if (cluster.isMaster) {
cluster.fork();
console.log('这段代码运行在主进程里');
} else {
http.createServer(function (req, res) {
if (req.url != '/favicon.ico') {
res.end('hello');
console.log('这段代码运行在子进程里');
}
}).listen(8080, 'localhost');
}
cluster.on('online', function (worker) {
console.log('已经收到子进程#' + worker.id + "的消息");
});
cluster.on('listening', function (worker, address) {
console.log('子进程中的服务器开始监听,地址为:' + address.address + ":" + address.port);
});
子进程中的Node.js应用程序默认运行当前正在运行的Node.js应用程序中的主模块文件。可以使用setupMaster方法修改子进程中运行的模块文件
cluster.setupMaster([settings]);
let cluster = require('cluster');
cluster.setupMaster({
exec: 'subtask.js'
});
cluster.fork();
console.log('这段代码被运行子主进程中');
console.log('cluster.settings属性值: %j', cluster.settings);
let http = require('http');
http.createServer(function (req, res) {
if (req.url != '/favicon.ico') {
res.writeHead(200);
res.end('ok');
console.log('这段代码被运行在子进程中');
}
}).listen(8080);
当在子进程里运行服务器时,客户端总是先被主进程接收,然后转发给子进程中的服务器。如果在多个子进程中运行服务器,当主进程接收到客户端请求后,将会自动分配给一个当前处于空闲状态的子进程。
let cluster = require('cluster');
let http = require('http');
if (cluster.isMaster) {
cluster.fork();
cluster.fork();
} else {
http.createServer(function (req, res) {
if (req.url !== '/favicon.ico') {
let sum = 0;
for (let i = 0; i < 1000000; i++) {
sum += i;
}
res.writeHead(200);
res.write(`客户端请求在子进程${cluster.worker.id}中被处理`);
res.end(`子进程${cluster.worker.id}中的计算结果=${sum}`);
}
}).listen(8080);
}
let cluster = require('cluster');
let http = require('http');
if (cluster.isMaster) {
cluster.setupMaster({
silent: true
});
let worker = cluster.fork();
worker.process.stdout.on('data', function (data) {
console.log('接收到来自客户端的请求,目标地址:' + data);
});
} else {
http.createServer(function (req, res) {
if (req.url !== '/favicon.ico') {
let sum = 0;
for (let i = 0; i < 1000000; i++) {
sum += i;
}
res.writeHead(200);
console.log(`客户端请求在子进程${cluster.worker.id}中被处理`);
res.write(`客户端请求在子进程${cluster.worker.id}中被处理`);
res.end(`子进程${cluster.worker.id}中的计算结果=${sum}`);
}
}).listen(8080);
}
当新建一个工作进程后,工作进程应当响应一个online消息给主进程。当主进程收到online消息后触发这个事件
let cluster = require('cluster');
let http = require('http');
if (cluster.isMaster) {
let worker = cluster.fork();
console.log('这段代码被运行在主进程里');
worker.on('online', function () {
console.log(`已经收到子进程${worker.id}的运行信息`);
});
} else {
http.createServer(function (req, res) {
if (req.url !== '/favicon.ico') {
let sum = 0;
for (let i = 0; i < 1000000; i++) {
sum += i;
}
res.end('ok');
console.log(`这段代码被运行在子进程中。`);
}
}).listen(8080);
}
在使用fork发放开启子进程后,可以使用fork方法所返回的worker对象的send方法在主进程中向子进程发送消息。
worker.send(message,[sendHandle]);//在主进程中向子进程发送消息
process.send(message,[sendHandle]);//在子进程中像主进程发送消息
process.on('message',function(m,setHandle){});
let cluster = require('cluster');
cluster.setupMaster({
exec: 'child.js'
});
let worker = cluster.fork();
worker.on('message', function (m) {
console.log('父进程接收到消息:', m);
process.exit();
});
worker.send({
name: 'zfpx'
});
let http = require('http');
let cluster = require('cluster');
let net = require('net');
cluster.setupMaster({
exec: '22.subsocket.js'
});
let worker = cluster.fork();
let server = require('net').createServer();
server.on('connection', function (socket) {
if (Date.now() % 2 == 0) {
worker.send('socket', socket);
} else {
socket.end('客户端的请求在主进程中处理');
}
});
server.listen(41234, 'localhost');
worker.on('message', function (m, socket) {
console.log(m);
});
process.on('message', function (msg, socket) {
if (msg == 'socket') {
socket.end('子进程中返回消息:' + msg);
process.send('告诉父进程我处理了一个消息');
}
});
当使用fork方法开启子进程后,可以使用fork方法返回的worker对象的kill方法强制关闭子进程
worker.kill([signal]);
当子进程退出时,将会触发worker对象的exit事件
worker.on('exit',function(code,signal));
let cluster = require('cluster');
let http = require('http');
if (cluster.isMaster) {
cluster.setupMaster({
silent: true
});
let worker = cluster.fork();
worker.process.stdout.on('data', function (data) {
console.log('接收到来自客户端的请求,目标地址为:' + data);
worker.kill(); //让子进程退出
});
worker.on('exit', function (code, signal) {
console.log(arguments)
//suicide可以判断是自动退出还是异常退出,退出之前时undefined.自动退出为true,异常退出为false
if (worker.exitedAfterDisconnect == true) {
console.log(`子进程%{worker.id}自动退出`);
} else if (worker.exitedAfterDisconnect == false) {
console.log(`子进程${worker.id}异常退出,退出代码为${code}`);
}
if (signal) {
console.log('退出信号为 %s', signal);
}
});
} else {
let server = http.createServer(function (req, res) {
if (req.url != '/favicon.ico') {
res.end('hello');
process.stdout.write(req.url);
}
}).listen(8080);
}
可以使用worker对象的disconnect方法使该子进程不再接收外部连接
let cluster = require('cluster');
let http = require('http');
if (cluster.isMaster) {
cluster.setupMaster({ silent: true });
let worker = cluster.fork();
worker.process.stdout.on('data', function (data) {
console.log('接收到来自客户端的请求,目标地址为:' + data);
setTimeout(function () {
worker.disconnect();//不再接收连接
worker.send('disconnect');
}, 2000);
});
worker.on('disconnect', function () {
console.log(`子进程${worker.id}断开连接`);
});
worker.on('exit', function (code, signal) {
if (worker.exitedAfterDisconnect) {
console.log(`子进程${worker.id}正常退出`);
} else {
console.log(`子进程${worker.id}异常退出`);
}
if (signal) {
console.log(' 退出信号为' + signal);
}
});
} else {
let http = require('http');
let server = http.createServer(function (req, res) {
if (req.url != '/favicon.ico') {
res.end('hello');
process.stdout.write(req.url);
}
}).listen(8080);
process.on('message', function (msg) {
if (msg == 'disconnect') {
//process.exit(0);
}
});
}