在nodejs中只支持单线程。但是在应用程序中,如果只使用单线程进行操作,从接受请求开始到返回响应为止的这一段时间内可能存在很长的一段等待时间。在这种场合下如果能使用多进程,则可以为每个请求分配一个进程,从而更好的使用服务器端的cpu资源。为了实现多进程处理,nodejs提供了child_process
模块于cluster
模块.其中child_process
模块用于实现在node.js
应用程序中开启多个子进程并在各个子进程中运行不同命令或执行node.js
模块文件。Cluster
模块用于实现node.js应用程序中开启多个子进程,在每个子进程中运行一个node.js
应用程序的副本
进程对象(process)属性
process
不是内置模块,而是一个全局对象,因此在任何地方都可以直接使用
属性列表:
execPath
:属性值用来运行应用程序的可执行文件的绝对路径。
version
:属性值为node.js的版本号
platform
:属性值是当前运行node的平台是Linux还是windows
argv
:属性值为一个数组,其中包含了运行node.js应用程序中所有的命令行参数。数组的第一元素为node 第二个元素为运行的脚本文件名 从第三个元素开始为其他的命令行参数
process.argv.forEach(function(val,index,array){
console.log(index+":"+val);
})
env
:此属性值为一个对象 其中包含了运行node程序操作系统的环境信息。
config
:词属性值为一个对象
【执行应用程序可执行文件的配置项】
pid
:当前应用程序进程的PID
title
:应用程序的窗口标题
stdin
:输入流对象
process.stdin.resume();
process.stdin.on('data',function(chunk){
process.stdout.write('进程接受到数据:'+chunk);
})
打印进程接受到的数据
sdout
:输出流对象
进程对象的方法与事件
process.memoryUsage()
获取运行node.js应用程序的进程内存使用量
Res
:属性值是一个整数 表示运行node.js应用程序的进程的内存消耗量
heapTotal
:表示V8所分配的内存量单位为字节
heapUsed
表示V8所消耗的内存量 单位为字节
在nodejs中只使用一个线程来执行所有的操作。因此如果在应用程序中存在某个操作需要大量消耗cpu资源状况,则其他操作都会受到一定影响。例如当服务器正在执行一个非常消耗cpu资源的操作,则在该操作执行之后接受到客户端请求都需要等待该操作执行完毕后才能被处理。
近些年来,服务器一般都开始使用多核cpu或者多cpu,许多服务器应用程序都开始依靠多线程或者多进程的机制来处理这些请求,以便可以更好的利用这些cpu的资源。在node.js中,同样提供一个child_process模块。通过该模块的使用,在node.js应用程序的主进程之后可以开启多个子进程。在多个子进程之间可以共享内存空间,可以通过子进程之间的相互通信来实现信息的交换。
子进程 模块 child_process
方法一
child_process.spawn(command,[args],[options])
Command
为必须指定的参数 值为字符串 用于指定需要运行的命令
Args
为数组 存放指定命令时需要使用的参数
Options
开启子进程使用的选项
spawn
方法返回一个隐式创建的代表子进程的ChildProcess
test1.js
process.stdout.write("子进程的工作目录是:"+process.cwd());
process.argv.forEach(function(val,index,array){
process.stdout.write("\r\n"+index+":"+val);
})
Test2.js
var fs=require('fs');
var out=fs.createWriteStream('./message.txt');
process.stdin.on('data',function(data){
out.write(data);
})
process.stdin.on('end',function(data){
process.exit();
})
Child.js
var cp=require('child_process');
var sp1=cp.spawn('node',['test1.js','one','two','three','four']);
console.log(sp1);
var sp2=cp.spawn('node',['test2.js',{stdio:'pipe'}]);
sp1.stdout.on('data',function(data){
console.log('子进程标准输出:'+data);
sp2.stdin.write(data);
});
sp1.on('exit',function(code,signal){
console.log('子进程退出,退出代码为'+code);
process.exit();
});
exec()
方法开启子进程
在child_process
模块中可以使用exec
方法开启一个用于运行某个命令的子进程并缓存子进程的输出结果
Child_process.exec(command,[options],[callbac])
Command
命令
Options 设置选项 例如设置当前目录 cwd 设置编码encoding
Function(error,stdout,stderr){
}
exec
方法返回一个隐式创建的代表子进程的ChildProcess
exec
方法与spawn
方法的区别:
Spawn
方法可以在父进程中实时接受子进程中的输出流数据 因此是一个异步方法
Exec
方法 父进程必须等待子进程的数据流全部缓存完毕后才能接受这些数据
Test1.js
process.stdout.write("子进程的工作目录是:"+process.cwd());
process.argv.forEach(function(val,index,array){
process.stdout.write("\r\n"+index+":"+val);
})
Test3.js
var fs=require('fs');
var out=fs.createWriteStream('./mess.txt');
process.stdin.on('data',function(data){
out.write(data);
process.exit();
})
Exec.js
var cp=require('child_process');
var sp1=cp.exec('node test1.js one two three four',function(err,stdout,stderr){
if(err){
console.log("子进程开启失败:"+err);
process.exit();
}else{
console.log('子进程输出标准:'+stdout.toString());
sp2.stdin.write(stdout.toString());
}
});
var sp2=cp.exec('node test3.js',function(err,stdou,stderr){
process.exit();
});