一、理论

之前看多进程这一章节时发现这块东西挺多,写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进程管理之子进程的更多相关文章

  1. Node.js进程管理之Process模块

    在前面Node.js事件运行机制也有提到,Node.js应用在单个线程运行,但是现在大部分服务器都是多处理器,为了方便使用多个进程,Node.js提供了3个模块.Process模块提供了访问正在运行的 ...

  2. Node.js进程管理之进程集群

    一.cluster模块 Node.js是单线程处理,对于高并发的请求怎么样能增加吞吐量呢?为了提高服务器的利用率,能不能多核的来处理呢?于是就有了cluster模块. cluster模块可以轻松实现运 ...

  3. Node.js进程通信模块child_process

    前言 Node.js是一种单线程的编程模型,对Node.js的赞美和诟病的也都是因为它的单线程模型,所有的任务都在一个线程中完成(I/O等例外).单线程模型,不仅让代码非常简洁,更是直接避免了线程调度 ...

  4. 深入理解 Node.js 进程与线程

    原文链接: https://mp.weixin.qq.com/s?__biz=MzAxODE2MjM1MA==&mid=2651557398&idx=1&sn=1fb991da ...

  5. Node.js包管理器Yarn的入门介绍与安装

    FAST, RELIABLE, AND SECURE DEPENDENCY MANAGEMENT. 就在昨天, Facebook 发布了新的 node.js 包管理器 Yarn 用以替代 npm .咱 ...

  6. Node.js包管理器:

    Node.js包管理器: 当我们要把某个包作为工程运行的一部分时,通过本地模式获取,如果要在命令行下使用,则使用全局模式安装 使用全局模式安装的包并不能直接在JavaScript文件中用require ...

  7. 避免uncaughtException错误引起node.js进程崩溃

    uncaughtException 未捕获的异常, 当node.js 遇到这个错误,整个进程直接崩溃. 或许这俩个人上辈子一定是一对冤家. 或许这俩个人经历了前世500次的回眸才换来了今生的相遇,只可 ...

  8. Node.js NPM 管理包

    章节 Node.js NPM 介绍 Node.js NPM 作用 Node.js NPM 包(Package) Node.js NPM 管理包 Node.js NPM Package.json 根据安 ...

  9. Node.js 进程

    process 是全局对象,能够在任意位置访问,是 EventEmitter 的实例. 退出状态码 当没有新的异步的操作等待处理时,Node 正常情况下退出时会返回状态码 0 .下面的状态码表示其他状 ...

随机推荐

  1. radom

    radom模块提供了随机生成对象的方法 Help on module random: NAME random - Random variable generators. FILE /usr/local ...

  2. 设计模式之状态模式(State Pattern)

    一.什么是状态模式? 把所有动作都封装在状态对象中,状态持有者将行为委托给当前状态对象 也就是说,状态持有者(比如汽车,电视,ATM机都有多个状态)并不知道动作细节,状态持有者只关心自己当前所处的状态 ...

  3. 设计模式之命令模式(Command Pattern)

    一.什么是命令模式? 命令模式,封装了方法调用细节,以解耦请求者与执行者,具体流程如下: 1.从请求者(客户)的角度看 请求者(客户)发出请求 -> 调用者(系统)构造命令对象封装请求 -> ...

  4. [ASP.NET]JQuery直接调用asp.net后台WebMethod方法

    在项目开发碰到此类需求,特此记录下经项目验证的方法总结. 利用JQuery的$.ajax()可以很方便的调用asp.net的后台方法. [WebMethod] 命名空间 1.无参数的方法调用 注意:方 ...

  5. C# winform 记住密码实现代码

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  6. .netcore与vue的学习笔记001

    1.dnc的js引用 需要引用的js文件要放在解决方案下的wwwroot目录下.否则将无法获取到指定js文件,出现404错误 2.vue的相关运用 0)通过new Vue并传入object来实例化一个 ...

  7. 哎呀,我艹,使用tfs时候,离职人员锁定了代码.

    哎呀,我艹,使用tfs时候,离职人员锁定了代码. 而且离职人员电脑已经回收,被格式化了,怎么破? 不管别人是有意,还是无意,总之就是需要搞定了. 1.第一步 首先,找到被锁住的工作区一般在报错信息中可 ...

  8. Django 项目 实现重定向并进行反向解析

    一.项目路由配置urls.py中 from django.conf.urls import include, url from django.contrib import admin # 匹配应用 u ...

  9. python stdout 重定向

    import sys class Buffer(object): def __init__(self): self.buffer = [] def write(self, *args, **kwarg ...

  10. 静态分析第三发 so文件分析(小黄人快跑)

    本文作者:i春秋作家——HAI_ 0×00 工具 1.IDA pro 2.Android Killer 0×01 环境 小黄人快跑 下载地址http://download.csdn.net/downl ...