当前位置: 首页 > 后端技术 > Node.js

Node.js学习之路14——进程

时间:2023-04-04 01:40:03 Node.js

Process在Node.js中,只支持单线程。但是,在一个应用中,如果只使用单线程进行操作,那么从接收请求到返回响应之间可能会有很长的等待时间。这种情况下,如果可以使用多进程,可以为每个请求分配一个进程,这样可以更好的利用服务器端的CPU资源。为了实现多线程处理,Node.js提供了child_process模块??和cluster模块。child_process模块用于在Node.js应用程序中启用多个子进程,并在每个子进程中运行各种命令或进程。执行Node.js模块文件并处理可执行文件。cluster模块用于实现在Node.js应用中启动多个子进程,并在每个子进程中运行一个Node.js应用的副本的处理。1、进程1.1进程对象的属性process.execPath:应用程序运行所用的可执行文件的绝对路径version:Node.js的版本号versions:Node.js及其依赖的版本号platform:当前正在运行节点。jsplatformstdin:用于读取标准输入流的对象。默认情况下,标准输入流被挂起,比如恢复读取标准输入流process.stdin.resume()stdout:用于写入标准输出流的对象stderr:用于写入标准错误输出流的对象等写入流数据的对象是不同的。process.stdout对象和process.stderr对象的写数据操作只有在使用其他读取流数据的对象的pipe方法,process.stdout对象或进程时才是阻塞操作。当stderr对象作为目标对象时,process.stdout对象和process.stderr对象的写数据操作是非阻塞操作。argv:该属性值是一个数组,包含运行Node.js应用程序时的所有命令行参数。env:有关运行Node.js应用程序的操作系统的信息config:包含用于编译当前Node.js应用程序的可执行文件的配置选项的JavaScript描述pid:运行当前Node.js应用程序的进程的PIDtitle:正在运行的标题当前Node.js应用程序arch的命令行窗口:运行当前Node.js应用程序的处理器架构,arm,ia32,x64等1.2进程对象的方法1.2.1内存使用memoryUsage()这个方法做不使用任何参数,返回一个对象,对象的属性如下rss:属性值为整数,表示运行Node.js应用的进程的内存消耗,单位为字节headTotal:属性值为整数,表示为V8分配的内存量,单位为byteheadUsed:该属性值为整数,表示V8的内存消耗量,单位为byte一个函数被推迟到代码中编写的下一个同步方法执行完成,或者异步方法的事件回调函数开始执行时。其作用与将setTimeout方法的事件参数值指定为0相同,但nextTick()方法中指定函数的调用速度要比setTimeout方法中指定函数的调用速度快很多。读取文件后调用nextTick()constprocess=require('process');constfs=require('fs');varfinish=function(){console.log('文件已读取');}process.nextTick(finish);console.log(fs.readFileSync('./fs.js').toString());指定两个同步执行的耗时操作constprocess=require('process');constfs=require('fs');functionfoo(){process.nextTick(Task);}functionTask(){varfile=fs.createReadStream('./fs.js');file.on('data',(data)=>{console.log('Task函数中,读取字节长度:',data.length);})}varfile=fs.createReadStream('./fs.js');file.on('data',(data)=>{console.log('全局读取字节长度:',data.length);});foo();在Node.js中,提供了一个process.maxTickDepth属性,默认属性值为1000,当递归深度达到process.maxTickDepth属性的值时,允许递归函数外的代码继续执行,但会发出警告提醒开发人员改为使用setImmediate方法。进程发送SIGABRT信号异常终止进程,同时生成core文件。该方法不使用任何参数1.2.4更改文件目录process.chdir()修改Node.js应用中使用的当前工作目录process.chdir(目录)参数可以是一个字符串,用于指定当前工作目录。该目录可以是相对路径或绝对路径。如果指定的路径不存在,则会报错。1.2.5返回当前目录process.cwd()constprocess=require('process');console.log('当前目录:'+process.cwd());process.chdir('../');console.log('上层目录:'+process.cwd());1.2.6退出程序process.exit()退出运行Node.js应用程序的进程,使用整数值参数指定操作系统的退出代码,代码0表示正常退出,不使用时的默认参数值parameteris01.2.7设置或返回进程的组IDprocess.getgid()返回运行Node.js应用程序的进程的组ID,该方法仅对非windows系统有效,请勿使用useanyparametersprocess.setgid(id)用于设置运行Node.js应用的进程的组ID,该方法只在非windows操作系统下有效,不使用任何参数setgid方法使用了一个参数,参数值可以是整数类型的组ID,也可以是字符串类型的组名。如果指定了组名,则组名会自动解析为组ID1.2.8设置或返回进程用户IDprocess.getuid()返回运行Node.js应用的进程的用户ID,该方法仅非windows操作系统下有效,不带任何参数process.setuid(id)用于设置运行Node.js应用的进程的用户ID,该方法仅在非windows操作系统下有效1.2.9发送信号到进程process.kill(pid,[signal])用于向进程发送信号。pid参数为必选参数,signal参数为可选参数,pid参数为整数,用于指定需要接收信号的进程ID。signal参数的值是一个字符串,用于指定要发送的信号,例如SIGINT或SIGUSR1。不使用该参数时,默认参数值为SIGTERM,表示进程终止1.2.9读取或修改进程的文件权限掩码umask([mask])用于读取或修改进程的文件权限掩码运行Node.js应用程序的进程。子进程会继承父进程的文件权限掩码参数来设置修改后的文件权限掩码。如果不使用该参数,则返回进程当前使用的文件的权限掩码。constprocess=require('process');varoldmask,newmask=0644;oldmask=process.umask(newmask);console.log('修改前的掩码:',oldmask.toString(8));console.log('修改后掩码:',newmask.toString(8));/*****修改前掩码:0*修改后掩码:644*/1.2.10时间返回当前运行时间(秒)process.uptime()测试代码运行时间process.hrtime()constprocess=require('process');lettime=process.hrtime();for(leti=0;i<1000;i++){}varendTime=process.hrtime(时间);控制台日志(结束时间);1.3进程对象事件1.3.1退出事件exitconstprocess=require('process');process.on('exit',()=>{console.log('Node.jsprogramexits');});process.exit();1.3.2UncaughtExceptionconstprocess=require('process');process.on('uncaughtException',(err)=>{console.log('CaughtanexceptionError',err);});undefinedFunction();1.3.3各种信号事件当运行Node.js应用程序的进程接收到各种事件时,会触发各种信号事件。你可以监听这些事件并指定事件回调函数的方法来处理信号,回调函数不需要任何参数。1.4创建多进程应用1.4.1使用spawn方法启动子进程child_process.spawn(command,[args],[options])command参数的值为字符串,指定命令的args作为一个数组运行,存储所有运行该命令所需的参数。参数的指定顺序与数组中元素的顺序一致。默认值为空。工作目录stdio:设置子进程的标准输入/输出customFds:数组,子进程的标准输入/输出指定文件描述符env:指定子进程的环境变量,不指定时没有可用环境变量detached:布尔值,子进程为进程组中的首进程uid:设置子进程的用户IDgid:设置子进程的组IDconstprocess=require('process');constcp=require('child_process');letsp1=cp.spawn('node',['test1.js','one','two','three'],{cwd:'./one'})让sp2=cp.spawn('node',['test2.js'],{stdio:'pipe'});sp1.stdout.on('data',(data)=>{console.log('subprocesssp1annotationoutput:',data);sp2.stdin.write(data);});sp1.on('exit',(code,signal)=>{console.log('子进程sp1退出,退出码为',code);process.exit();});