一、理论

之前看多进程这一章节时发现这块东西挺多,写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. java多线程 —— 两种实际应用场景模拟

    最近做的偏向并发了,因为以后消息会众多,所以,jms等多个线程操作数据的时候,对共享变量,这些要很注意,以防止发生线程不安全的情况. (一) 先说说第一个,模拟对信息的发送和接收.场景是这样的: 就像 ...

  2. nginx优化笔记(keepalive、https等)

    一.nginx之tcp_nopush.tcp_nodelay.sendfile 1.TCP_NODELAY你怎么可以强制 socket 在它的缓冲区里发送数据?一个解决方案是 TCP 堆栈的 TCP_ ...

  3. 《ASP.NET MVC 5 破境之道》:概述

    第一节:写作本书的目的 关于笔者 张晓亭(Mike Cheers),1982年出生,内蒙古辽阔的大草原是我的故乡. 没有高学历,没有侃侃而谈的高谈阔论,拥有的就是那一份对技术的执著,对自我价值的追求. ...

  4. 关于margin:-10000px;padding:10000px;的理解

    原文链接: 内外补丁负值法是指通过内外补丁的设置来解决一些我们通常方法不能实现的效果.例如:可以通过改变盒模型的样式来使几列div由内容撑开高度但几列div与最高的一栏等高的问题.但是为什么会出现这样 ...

  5. Android Studio无法连接真机的问题?

    我不说,你可能又浪费半天时间,最后的结果,你可能还是没能解决!!! 现在,一般安卓手机为了安装软件方便,一般都安装了豌豆荚,但是,就是这个豌豆荚占用了Android Studio的ADB端口,导致An ...

  6. VC API常用函数简单例子大全(1-89)

    第一个:FindWindow根据窗口类名或窗口标题名来获得窗口的句柄,该函数返回窗口的句柄 函数的定义:HWND WINAPI FindWindow(LPCSTR lpClassName ,LPCST ...

  7. 鬼知道是啥系列之——STL(lower_bound(),upper_bound() )

    引子,不明觉厉:   百度,渐入佳境: 头铁,入门到放弃: lower_bound(): 头文件:  #include<algorithm>函数功能:  函数lower_bound()在f ...

  8. linux parallel rsync 拷贝N多文件

    先来个对比图看一下, 左边图是普通 rsync 目录拷贝, 右边图是借助 parallel 工具并发起了多个 rsync centos6.5安装 parallel #!/bin/bash # Inst ...

  9. 读Lock-Free论文实践

    论文地址:implementing Lock-Free Queue 论文大体讲的意思是:Lock-Base的程序的performance不好,并且a process inside the critic ...

  10. 《JAVA与模式》之代理模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述代理(Proxy)模式的: 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 代理模式的结 ...