Node.js进程管理之子进程
一、理论
之前看多进程这一章节时发现这块东西挺多,写Process模块的时候也有提到,今天下午午休醒来静下心来好好的看了一遍,发现也不是太难理解。
Node.js是单线程的,对于现在普遍是多处理器的机器是一种浪费,怎么能利用起来呢?于是child_process模块出现了。child_process模块可以在其他进程上产生、派生,并执行工作。
child_process模块提供了一个ChildProcess的新类,它可以作为从父进程访问子进程的表示形式。Process模块也是ChildProcess对象。当你从父模块访问process时,它是父ChildProcess对象,当你从子进程访问Process是,它是ChildProcess对象
了解一个对象无外乎事件、方法、属性。ChildProcess也是一样。下面列出一些常用的事件、方法和属性。
事件:
message:当ChildProcess对象调用send()方法来发送数据时触发。
error:在工作进程中出现错误时发出。该处理程序接收一个错误对象作为唯一的参数。
exit:当工作进程结束时发出。该处理程序接收两个参数,code,signal.
close:当工作进程的所有stdio流都已经终止的时候发出。与exit不同的是,因为多个进程可以共享相同的stdio流。
disconnect:当disconnect()在一个工作进程上被调用时发出。
方法:
kill([signal]):导致操作系统发送一个kill信号给子进程。默认是SIGTERM.
send(message,[sendHandle]):将消息发送到句柄。消息可是字符串或对象。sendhandle可以把TCP Server或socket对象发送到客户端。这允许客户端进程共享相同的端口和地址。
disconnect():关闭父进程与子进程之间的进程通信(或IPC)通道,并把父进程和子进程的连接标志都设置为false。
属性:
stdin:输入Writable流。
stdout:标准输出Readable流。
strerr:用于输出错误的标准输出Readable流。
pid:进程的ID。
connected:一个布尔值。在disconnect()被调用后,它被设置为false,当是false时,就不能将消息发送给子进程。
二、实践
1.exec()在另一进程执行一个系统命令
exec()函数在一个子shell中执行系统命令。几乎可以执行能从控制台提示符下执行的任何东西,如二进制可执行文件、shell脚本、Python脚本或批处理文件。
exec(command,[options],callback)函数返回一个ChildProcess对象
command:字符串,指定在子shell中执行的命令。
options:对象,指定执行命令时使用的设置。选项如下:
cwd:指定子进程执行的当前工作目录
env:一个对象,指定property:value作为环境的键/值对
encoding:指定存储命令的输出时输出缓冲区使用的编码
maxBuffer:指定stdout、stderror输出缓冲区的大小。默认200*1024.
timeout:指定父进程在杀掉子进程之前,如果子进程未完成等待的毫秒数。默认0
killSignal:指定终止子进程时使用的kill信号。默认SIGTERM。
callback:接收error、stdout、stderr3个参数。
var childProcess = require('child_process');
var options = {maxBuffer:100*1024, encoding:'utf8', timeout:5000};
var child = childProcess.exec('dir /B', options,
function (error, stdout, stderr) {
if (error) {
console.log(error.stack);
console.log('Error Code: '+error.code);
console.log('Error Signal: '+error.signal);
}
console.log('Results: \n' + stdout);
if (stderr.length){
console.log('Errors: ' + stderr);
}
});
child.on('exit', function (code) {
console.log('Completed with code: '+code);
});
"C:\Program Files (x86)\JetBrains\WebStorm 11.0.3\bin\runnerw.exe" F:\nodejs\node.exe child_process_exec.js
Completed with code: 0
Results:
chef.js
child_fork.js
child_process_exec.js
child_process_exec_file.js
child_process_spawn.js
cluster_client.js
cluster_server.js
cluster_worker.js
file.txt
process_info.js Process finished with exit code 0
2.execFile()在另一个进程上执行一个可执行文件
它与exec()相似,不同的是execFile()没有使用子shell,执行的命令必须是一个二进制可执行文件Linux的shell脚本和Windows的批处理文件不能使用ecexFile().
execFile(file,args,options,callback)也是返回一个ChildProcess。
file:字符串,执行要执行的可执行文件的路径。
args:数组,指定传递给可执行文件的命令行参数。
options:参考exec()的。
callback:参考exec().
var childProcess = require('child_process');
var options = {maxBuffer:100*1024, encoding:'UTF-16', timeout:5000};
var child = childProcess.execFile('ping.exe', ['-n', '1', 'baidu.com'],
options, function (error, stdout, stderr) {
if (error) {
console.log(error.stack);
console.log('Error Code: '+error.code);
console.log('Error Signal: '+error.signal);
}
console.log('Results: \n' + stdout.toString());
if (stderr.length){
console.log('Errors: ' + stderr.toString());
}
});
child.on('exit', function (code) {
console.log('Child completed with code: '+code);
});
3.spawn()在另一个Node.js实例中产生一个进程
spawn(cmd,[args],[options])函数产生一个进程,连接它们之间的stdio、stdout、stderr的管道,然后在新的线程中使用spawn()执行文件。它和上面两个的主要区别是产生的进程中的stdin可以进行配置,并且stdout、stderr都是父进程中的Readable流。这意味着exec()、execFile()必须先执行完成,才能读取缓冲区输出,但一旦一个spawn()进程的输出数据已被写入就可以读取它(这个可以从它们3个的输出结果的顺序可以看出,上面两个都是先执行exit事件,而spawn()exit处理是在后面)。
cmd、args和上面两个的一样。options也可以设置cwd、env,还可以设置detached、stdio。
detached:布尔值,true时使子进程成为新进程组的组长,即使父进程退出,也会继续,可以使用child_unref()使得父进程退出之前不等待子进程
stdio:定义子进程stdio配置([stdin,stdout,stderr]).默认[0,1,2].此字符串定义每个输入输出流的配置。
var spawn = require('child_process').spawn;
var options = {
env: {user:'brad'},
detached:false,
stdio: ['pipe','pipe','pipe']
};
var child = spawn('netstat', ['-e']);
child.stdout.on('data', function(data) {
console.log(data.toString());
});
child.stderr.on('data', function(data) {
console.log(data.toString());
});
child.on('exit', function(code) {
console.log('Child exited with code', code);
});
4.实现子派生
Node.js提供了另外一种进程产生方式——派生。它主要是执行在一个单独的处理器上运行另外一个V8引擎实例中的Node.js模块代码。可以用派生来并行运行多个服务。不过这需要时间来运转V8的一个新实例,每个实例需要大约10M的内存,所以应该把派生的进程设计为存活期更长的,不需要大量派生的进程。与spawn不同的是,它不能为子进程配置stdio。可以使用ChildProcess对象中的send()机制在父进程与子进程间通信。
fork(modulePath,[args],[options])对象也是返回一个ChildProcess对象。
modulePath:字符串,指定被新的Node.js实例启动的JavaScript文件路径。
args:数组,指定传递给node命令的命令行参数。
options:参数对象,指定执行命令时使用的设置。
cwd、env上面有。
encoding:指定数据写入输出流时和穿越send()IPC机制时使用的编码
execPath:指定用于创建产生Node.js进程的可执行文件。
silent:一个布尔值,true时将导致派生的进程中的stdout和stderr不与父进程相关联,默认false。
Child.send()父进程向子进程发送消息,Process.send()是子进程向父进程发送消息。
var child_process = require('child_process');
var options = {
env:{user:'Brad'},
encoding:'utf8'
};
function makeChild(){
var child = child_process.fork('chef.js', [], options);
child.on('message', function(message) {
console.log('Served: ' + message);
});
return child;
}
function sendCommand(child, command){
console.log("Requesting: " + command);
child.send({cmd:command});
}
var child1 = makeChild();
var child2 = makeChild();
var child3 = makeChild();
sendCommand(child1, "makeBreakfast");
sendCommand(child2, "makeLunch");
sendCommand(child3, "makeDinner");
process.on('message', function(message, parent) {
var meal = {};
switch (message.cmd){
case 'makeBreakfast':
meal = ["ham", "eggs", "toast"];
break;
case 'makeLunch':
meal = ["burger", "fries", "shake"];
break;
case 'makeDinner':
meal = ["soup", "salad", "steak"];
break;
}
process.send(meal);
});
"C:\Program Files (x86)\JetBrains\WebStorm 11.0.3\bin\runnerw.exe" F:\nodejs\node.exe child_fork.js
Requesting: makeBreakfast
Requesting: makeLunch
Requesting: makeDinner
Served: ham,eggs,toast
Served: burger,fries,shake
Served: soup,salad,steak
上面的代码是在主进程中创建3个子进程,父进程给子进程发消息,子进程接收并给父进程发消息。
Node.js进程管理之子进程的更多相关文章
- Node.js进程管理之Process模块
在前面Node.js事件运行机制也有提到,Node.js应用在单个线程运行,但是现在大部分服务器都是多处理器,为了方便使用多个进程,Node.js提供了3个模块.Process模块提供了访问正在运行的 ...
- Node.js进程管理之进程集群
一.cluster模块 Node.js是单线程处理,对于高并发的请求怎么样能增加吞吐量呢?为了提高服务器的利用率,能不能多核的来处理呢?于是就有了cluster模块. cluster模块可以轻松实现运 ...
- Node.js进程通信模块child_process
前言 Node.js是一种单线程的编程模型,对Node.js的赞美和诟病的也都是因为它的单线程模型,所有的任务都在一个线程中完成(I/O等例外).单线程模型,不仅让代码非常简洁,更是直接避免了线程调度 ...
- 深入理解 Node.js 进程与线程
原文链接: https://mp.weixin.qq.com/s?__biz=MzAxODE2MjM1MA==&mid=2651557398&idx=1&sn=1fb991da ...
- Node.js包管理器Yarn的入门介绍与安装
FAST, RELIABLE, AND SECURE DEPENDENCY MANAGEMENT. 就在昨天, Facebook 发布了新的 node.js 包管理器 Yarn 用以替代 npm .咱 ...
- Node.js包管理器:
Node.js包管理器: 当我们要把某个包作为工程运行的一部分时,通过本地模式获取,如果要在命令行下使用,则使用全局模式安装 使用全局模式安装的包并不能直接在JavaScript文件中用require ...
- 避免uncaughtException错误引起node.js进程崩溃
uncaughtException 未捕获的异常, 当node.js 遇到这个错误,整个进程直接崩溃. 或许这俩个人上辈子一定是一对冤家. 或许这俩个人经历了前世500次的回眸才换来了今生的相遇,只可 ...
- Node.js NPM 管理包
章节 Node.js NPM 介绍 Node.js NPM 作用 Node.js NPM 包(Package) Node.js NPM 管理包 Node.js NPM Package.json 根据安 ...
- Node.js 进程
process 是全局对象,能够在任意位置访问,是 EventEmitter 的实例. 退出状态码 当没有新的异步的操作等待处理时,Node 正常情况下退出时会返回状态码 0 .下面的状态码表示其他状 ...
随机推荐
- 在循环中使用鼠标悬停时表示当前悬停选中,传入this关键字即可
在前端循环中使用鼠标悬停事件 <div class="message-widget contact-widget"> <!-- Message --> {% ...
- sql添加字段说明
1,sql字段说明 添加 exec sp_addextendedproperty N'MS_Description', N'主键', N'user', N'dbo', N'table', N'Fre ...
- item style edit in sharepoint 2013
标题头添加属性:(如果需要使用ddwrt)xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime&quo ...
- Spring boot创建定时任务
基于spring boot的应用创建定时任务不要太简单,给一个类加上@Configuration @EnableScheduling注解,然后给该类需要定时执行的方法加上@Scheduled(cron ...
- 「BZOJ1095」[ZJOI2007] Hide 捉迷藏
题目描述 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特,由N个屋子和N-1条双向走廊组成,这N-1条 ...
- Codeforces Round #452 (Div. 2) C. Dividing the numbers(水)
C. Dividing the numbers Petya has n integers: 1, 2, 3, ..., n. He wants to split these integers in t ...
- 聊聊并发(三)Java线程池的分析和使用
1. 引言 合理利用线程池能够带来三个好处.第一:降低资源消耗.通过重复利用已创建的线程降低线程创建和销毁造成的消耗.第二:提高响应速度.当任务到达时,任务可以不需要的等到线程创建就能立即执行. ...
- [ActionScript 3.0] UDP通信
package com.controls.socket { import flash.events.DatagramSocketDataEvent; import flash.events.Event ...
- nodejs实现请求代理
通常我们常用的请求方法只有GET.POST.PUT和DELETE,所以在此只介绍这四种和文件上传的代理方式 在此我们使用request.js第三方模块实现 GET(DELETE同GET,将reques ...
- 简单HOG+SVM mnist手写数字分类
使用工具 :VS2013 + OpenCV 3.1 数据集:minst 训练数据:60000张 测试数据:10000张 输出模型:HOG_SVM_DATA.xml 数据准备 train-images- ...