js 获取father_(原创)Node.JS实战26:强大的工作池。收藏吧!你一定会用的到。...

在实际项目中,如果遇到需要大计算量的操作,按需fork(分叉)其实不是一个好的选择。

因为fork的子进程也是V8(NodeJS的核心引擎)的新实例,每创建一个新实例,需要约30毫秒启动时间,和至少10MB的初始内存。

也就是说,创建进程是有代价的,你不能创建太多,也不能频繁创建。那样,达不到提高进程效率的目的。

那么,该如何高效优雅的使用子进程呢?工作池!

工作池!

合理的办法是创建一个可用的工作池,在池中存放足够多的进程,并可以随时分配使用。

我们对上一节讲的内容进行升级:当父进程发送一个任务给子进程时,子进程执行任务。并将结果向主进程反馈。

在父进程中,需要的代码会是这样的:

function doWork(job,cb){var child = cp.fork("./worker");//发送工作给子进程child.send(job);//希望子进程返回一个确切的消息child.once("message",function(result){cb(null,result);})
}

嗯...这样讲有些凌乱,这一章比较复杂,最好的办法,还是写一个完整的代码,做为例子:

aeec6c154f8f34a01167aca481af8454.png

1、father.js,主进程

var http = require("http");
var makePool = require("./pooler");
var runJob = makePool("./worker");http.createServer(function(req,res){runJob("some dummy job",function(er,data){console.log("father callback get:",data);if(er){return res.end("get an error:"+er.message)}res.end("work pool");})}).listen(8000)

当有客端访问时,触发runjob,开始启行工作。

2、worker.js

process.on("message",function(job){console.log("worker get msg:",job);for(var i=0;i<10;i++){console.log("worker send:",job,i);process.send("finish job:"+job+i);}})

收到father主进程发来的消息时,使用process.send()方法调用子进程,向工作池发出工作任务。

3、pool.js(工作池)

接收worker消息,用工作池完成操作,并反馈给主程序。

代码中做了详细的注释 ,就不单独对代码做解析了:

var cp = require("child_process");
//获取CPU数量,有几个CPU就创建几个子进程,这样就可以最大化的利用机器性能
var cpus = require("os").cpus().length;//模块导出函数
module.exports = function(workModule){//等待任务队列,当工作任务被下发,但没有闲工作进程时,放到此队列var awaiting = [];//存放准备就绪的工作进程var readyPool = [];//当前的工作子进程数量(工作池的大小)var poolSize = 0;return function doWork(job,cb){//如果工作池数量已经最大,并且没有准备就绪的工作子进程,也就是所有工作子进程都在工作中,那么:排队等待if(!readyPool.length && poolSize >cpus){//压入到等待队列,等待后续处理return awaiting.push([dowork,job.cb]);}//取得一个可用的工作子进程,或fork(分叉)一个新的子进程(增加工作池的大小)var child = readyPool.length ? readyPool.shift() : (poolSize++, cp.fork(workModule));{//子进程是否完成回调的标记var cbTriggered = false;//初始阶段,移除子进程上的监听,确保每个子进程只拥有一次监听child.removeAllListeners();//错误child.once("error",function(err){//未回调if(!cbTriggered){//回调返回为错误cb(err);//回调标识改为true:已回调cbTriggered = true;} //结束子进程child.kill();//这里不用操作工作池poolSize--,因为kill会触发exit事件,在exit事件中操作工作池});//子进程退出了(不明原因的意外退出、被kill()等都触发)child.once("exit",function(code,signal){//未回调if(!cbTriggered){//回调,返回信息cb(new Error("Child exited with code:"+code))}//工作池(正在工作的子进程数)大小减一poolSize --;//退出的子进程,是否在准备好的子进程数组中var childIdx = readyPool.indexOf(child);if(childIdx > -1){//从准备好的子进程数组中移除readyPool.splice(childIdx,1);}})//获取父进程发来的消息child.on("message",function(msg){console.log("pool get msg:",msg);cb(null,msg);cbTriggered = true;readyPool.push(child);//如何等待区有内容,处理之if(awaiting.length){setImmediate.apply(null,awaiting.shift());}//向父进程发送消息}).send(job);}//child区域结束}
}

执行效果

1b6fabc7b6b599c64fcc4c7ff81d447e.png

图中展示的是工作流程,可见此种方法可以达到我们的预期,工作池很OK。

对于实际编程中遇到的消耗比较大的情况,使用此种方法可以极大的提高效率,且本文已经将工作池写成了模块(pooler.js)

建议收藏,nodejs开发,在某个时候一定会遇到适合的场景的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372949.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

具有ReadWriteLock的Java并发

编写多线程Java应用程序并不是小菜一碟。 必须格外小心&#xff0c;因为同步不良会使您的应用程序一s不振。 JVM堆由所有线程共享。 如果多个线程需要同时使用相同的对象或静态类变量&#xff0c;则必须谨慎管理对共享数据的线程访问。 从1.5版开始&#xff0c;JSDK中包含了在并…

修复steam服务器失败,steam服务器链接失败

steam服务器链接失败 内容精选换一换当NTP服务器异常时产生该告警。当NTP服务器异常消除时&#xff0c;该告警恢复。主OMS节点配置的NTP服务器异常&#xff0c;可能会导致主OMS节点与外部服务器不能同步时间&#xff0c;集群时间可能会产生飘移。NTP服务器网络异常。与NTP服务器…

qemu-kvm简单使用

qemu-kvm主要有以下几个选项: -snapshot: 创建快照-m: 指定内存大小-smp: 指定处理器个数-cpu: 指定CPU类型-name: 设置虚拟机名称-vnc: 使用vnc连接-boot: 指定启动相关的选项-net: 指定网卡相关的选项-drive: 指定硬盘/光盘相关的选项qemu-kvm -m 128 -name first -smp 2 -dr…

将jar添加到发布目录_第32批免购置税新能源车型目录发布;通用BEV3平台将入华...

1、第32批免购置税新能源车型目录发布&#xff0c;几何X/理想ONE等283款车型入选6月2日&#xff0c;工信部发布《免征车辆购置税的新能源汽车车型目录(第三十二批)》&#xff0c;共有283款新能源车型入选。其中新能源乘用车方面包括&#xff0c;一汽大众Q2L/e-BORA、东风风神E7…

HPROF –内存泄漏分析教程

本文将为您提供有关如何通过生成和分析Sun HotSpot JVM HPROF堆转储文件来分析JVM内存泄漏问题的教程。 一个现实的案例研究将用于此目的&#xff1a;Weblogic 9.2内存泄漏影响Weblogic Admin服务器。 环境规格 Java EE服务器&#xff1a;Oracle Weblogic Server 9.2 MP1 中…

mq服务器与客户端消息同步,使用 ActiveMQ 实现JMS 异步调用

目录简介服务之间的同步调用&#xff0c;可以使用 HTTP 或 RPC 来完成&#xff0c;但并非所有的调用都需要同步&#xff0c;有些场景下&#xff0c;当客户端调用服务端时&#xff0c;并不需要等待服务端做出响应&#xff0c;此时就应该使用异步调用。异步调用的常用方式是基于 …

多个数字数组_七个问题帮助初学者深入理解Java数组

短文涨姿势&#xff0c;看了不白看&#xff0c;不关注等啥&#xff1f;几乎所有的高级语言当中&#xff0c;都提供了一种叫做”数组”的东西&#xff0c;Java语言当然也不例外。我们通过数组可以很方便的存储和管理一组数据。因为在Java语言当中使用数组非常的方便&#xff0c;…

java 异常练习题1

建立exception包&#xff0c;建立Bank类&#xff0c;类中有变量double balance表示存款,Bank类的构造方法能增加存款&#xff0c;Bank类中有取款的发方法withDrawal(double dAmount),当取款的数额大于存款时,抛出InsufficientFundsException,取款数额为负数&#xff0c;抛出Nag…

大话设计模式读书笔记--6.原型模式

简单的复制粘贴极有可能造成重复代码的灾难, 但是java中提供了克隆的功能, 如果一个对象创建过程复杂,又要频繁使用, 在初始化信息不发生变化的情况下,应当采取克隆而不是new一个对象 定义 原型模式: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象 也就是说,…

Java 7#8:测试台上的NIO.2文件通道

关于新JDK 7功能的另一篇博客文章。 这次我正在写有关新的AnsynchronousFileChannel类的文章。 我将在两周内深入分析新的JDK 7功能&#xff0c;并决定连续编号我的帖子。 只是为了确保我不会感到困惑&#xff1a;-)这是我关于Java 7的第七篇文章&#xff08;我承认–碰巧–这也…

5页面title样式修改_认识html:实现网站页面是这么简单的一回事

互联网时代人们通过上网浏览信息&#xff0c;打开浏览器上网看到丰富的图文、视频、音乐等多媒体信息&#xff0c;一系列信息反馈和视觉冲击之后&#xff0c;您有没有想过&#xff0c;互联网这么发达的时代&#xff0c;您觉得花一点点时间学会做个网站页面不真香&#xff1f;概…

iOS指南针

前言&#xff1a; 这个小项目使用到了CoreLocation框架里面的设备朝向功能&#xff0c;对CoreLocation感兴趣的可以翻一下之前的文章 在另一个博客站有朋友发现一个尴尬的问题&#xff08;图片的东西2个方向是不对的&#xff09;&#xff0c;原谅我的大意&#xff0c;赶时间就直…

OSGI –模块化您的应用程序

由于我是模块化&#xff0c;低耦合&#xff0c;高凝聚力等的大力拥护者&#xff0c;所以…… 我相信这项技术是我们使用Java平台创建应用程序的突破。 使用OSGi&#xff0c;创建高度可扩展的应用程序非常简单&#xff0c;例如参见Eclipse IDE。 我的目的不是要深入展示该技术的…

jq的链式调用.end();

jq的链式调用.end(); 先上code <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><style>li{list-style: none;width: 100px;height:20px;border:1px solid #ff0000;display: …

三、自定义视图、视图控制器

1.自定义视图 自定义视图&#xff1a;系统标准UI之外&#xff0c;自己组合而出的新的视图。在实际开发中&#xff0c;我们经常需要自己定义视图&#xff0c;积累自己的代码库。自己封装的视图&#xff0c;能像系统提供的UI控件一样用于多个项目中&#xff0c;这样可以提高我们的…

程序如何在两个gpu卡上并行运行_深度学习分布式训练相关介绍 - Part 1 多GPU训练...

本篇文章主要是对深度学习中运用多GPU进行训练的一些基本的知识点进行的一个梳理文章中的内容都是经过认真地分析&#xff0c;并且尽量做到有所考证抛砖引玉&#xff0c;希望可以给大家有更多的启发&#xff0c;并能有所收获介绍大多数时候&#xff0c;梯度下降算法的训练需要较…

集成Spring和JavaServer Faces:改进的模板

随着2.0版的发布&#xff0c;Facelet模板成为JSF规范的核心部分。 使用<ui&#xff1a;composition>和<ui&#xff1a;decorate>标记&#xff0c;可以轻松构建复杂的页面&#xff0c;同时仍保持标记清晰。 模板在创建HTML表单时特别有用&#xff0c;但是不幸的是&a…

whmcs模板路径

whmcs网站根目录 比如你的域名是server.nongbin.vip&#xff0c;你需要cd /home/wwwroot/server.nongbin.vip&#xff0c;该目录下然后&#xff0c;cd template/ 给文件夹下就是你上传的模板文件夹转载于:https://www.cnblogs.com/nongbin/p/6412108.html

系统英伟达gpu驱动卸载_绕过CPU,英伟达让GPU直连存储设备

英伟达最近发布了一个新的GPUDirect Storage&#xff0c;暂且叫做GPU直连存储&#xff0c;让GPU直接连到NVMe存储设备上。这一方案用到了RDMA设备来把数据从闪存存储转移到GPU本地的内存里&#xff0c;无需经过CPU还有系统内存。如果这一举措顺利的话&#xff0c;英伟达就能摆脱…

37、EnumSet详解

EnumSet类也是有顺序的&#xff0c;EnumSet按照枚举值在Enum类内定义的顺序决定集合元素的顺序 EnumSet在内部已位向量的形式存储&#xff0c;这种存储方式非常紧凑、搞笑&#xff0c;因此EnumSet占用内存很小&#xff0c;而且运行效率很好。 EnumSet集合不允许加入null元素 En…