宝哥软件园

深入了解Node.js的流程管理

编辑:宝哥软件园 来源:互联网 时间:2021-08-27

众所周知,Node基于V8,JavaScript运行在V8中的单线程上。这里的单线程并不意味着Node启动时只有一个线程,而是JavaScript代码在单线程上运行,Node有其他线程,比如异步IO操作的IO线程。这种单线程模式的优点是系统调度过程中不会频繁发生上下文切换,提高了单核CPU的利用率。

但是这种方法有一个缺陷,就是我们不能利用服务器CPU的多核性能,一个Node进程只能利用一个CPU。一旦代码在单线程模式下崩溃,整个程序就会崩溃。通常的解决方案是使用Node的集群模块,通过主从模式启用多个流程实例。下面详细讲一下Node如何使用多进程模型和多核CPU,以及自身集群模块的具体工作原理。

如何创建子进程

节点提供创建子流程的child_process模块,有四种创建子流程的方法。

const { spawn,exec,execFile,fork }=require(' child _ process ')spawn(command[,args][,options])exec(command[,options][,callback])execFile(file[,args][,options][,callback])fork(modulePath[,args][,options]]span)

首先,了解产卵方法。这是节点文档的正式示例。

const { spawn }=require(' child _ process ');const child=产卵(' ls ',['-lh ','/home ']);Child.on ('close ',(code)={console.log(`子进程退出代码:$[code]`));});const { stdin,stdout,stderr }=childstdout.on('data ',(data)={ console . log(` stdout : $ { data } `));});stderr.on('data ',(data)={ console . log(` stderr : $ { data } `));});由spawn创建的子进程继承自EventEmitter,因此它可以监视其上的事件(折扣、错误、关闭、消息)。同时,子进程有三个iostream: stdin、stdout和stderr。通过这三个流,可以实时获取子过程的输入输出和误差信息。

这个方法的最终实现是基于libuv的,所以这里就不讨论了。如果你感兴趣,可以查看源代码。

//调用libuv的api来初始化一个进程interr=uv _ spawn (env-event _ loop(),wrap-process _,options);exec/execFile

这两个放在一起的原因是execFile方法最终被exec调用。唯一不同的是,在exec中调用的normalizeExecArgs方法将默认将opts的shell属性设置为true。

exports . exec=function exec(/* command,options,callback */){ const opts=normalizexecargs . apply(null,arguments);return exports . exec file(opts . file,opts.options,opts . callback);};函数normalizeExecArgs(命令、选项、回调){ options={.选项};options . shell=type of options . shell===' string '?options.shell : true返回{ options };}在execFile中,最终调用了产卵方法。

exports . exec file=function exec file(file/*,args,options,callback */){ let args=[];让回调;让选项;var child=产卵(文件,参数,{ //.一些选项});返回孩子;}exec会将spawn的iostream转换为String,默认情况下会使用String

更多资讯
游戏推荐
更多+