nodejs制作一个简单线程池

ThreadPool 类

const { Worker,parentPort,isMainThread } = require('worker_threads')
//主线程
if(isMainThread){class ThreadPool {size = 5;queue = [];workerGroup = [];free=0;maxFree=2;monitor=null;constructor(size) {this.size = size;}//初始化子线程init(){for (let i = 0; i < this.size; i++) {this.workerGroup.push({id: i,status: false,worker: new Worker(__filename)});this.workerGroup[i].worker.on("message", (message) => {if (message === 'end') {this.workerGroup[i].status = false;this.check();}});}this.monitor=setInterval(()=>{if(this.isFree()){this.free++;console.log(`空闲次数: ${this.free},如果超过${this.maxFree}次,线程池将关闭,后续提交任务将自动开启`)}else{this.free=0;}this.check();if(this.free>this.maxFree){this.shutdown();clearInterval(this.monitor);this.monitor=null;this.workerGroup = [];this.free=0;}},10000)}isFree(){for (let i = 0; i < this.workerGroup.length; i++) {if (this.workerGroup[i].status) {return false;}}if(this.queue.length>0){return false;}return true;}//清理所有子线程shutdown() {this.workerGroup.forEach(e => {e.worker.terminate();});}/*** 提交异步任务* @param {*} taskContext  任务函数* @param {*} data 任务所需参数*/submitAsync(taskContext,data) {this.add(true,taskContext,data)}/*** 提交同步任务* @param {*} taskContext  任务函数* @param {*} data 任务所需参数*/submit(taskContext,data) {this.add(false,taskContext,data)}//添加任务排队add(isAsync,taskContext,data){if(this.workerGroup.length<1)this.init();//懒加载this.queue.push({isAsync:isAsync,data:data,taskContext:taskContext.toString()});this.check();}//检查任务check() {if(this.queue.length>0){for (let i = 0; i < this.workerGroup.length; i++) {if (!this.workerGroup[i].status) {this.workerGroup[i].status = true;this.workerGroup[i].worker.postMessage(this.queue.pop());break;}}}}}module.exports = ThreadPool;
}else{//子线程//监听任务parentPort.on("message", (task) => {if(task.isAsync){let taskContext=eval("("+task.taskContext+")")taskContext(()=>{parentPort.postMessage('end')//通知主线程任务结束},task.data);}else{let taskContext=eval("("+task.taskContext+")")taskContext(task.data);parentPort.postMessage('end')//通知主线程任务结束}})
}

使用方式


const ThreadPool = require('./ThreadPool');
const pool = new ThreadPool(2);let data = { name: '你好' }// 异步任务
pool.submitAsync(end => {setTimeout(() => {console.log("任务一开始" + new Date().getTime());let num = 0;while (true) {num++;if (num > 100000000) {console.log("任务一结束" + new Date().getTime());break;}}end();}, 1000);
});//异步任务+入参
pool.submitAsync((end, data1) => {setTimeout(() => {let num = 0;console.log("任务二开始" + new Date().getTime() + ",data=" + JSON.stringify(data1));while (true) {num++;if (num > 100000000) {console.log("任务二结束" + new Date().getTime());break;}}end();}, 1000);
}, data);//同步任务
pool.submit(data1 => {console.log("任务一开始" + new Date().getTime() + ",data" + JSON.stringify(data1));let num = 0;while (true) {num++;if (num > 100000000) {console.log("任务一结束" + new Date().getTime());break;}}}, data);//同步任务+入参
pool.submit(data1 => {console.log("任务二开始" + new Date().getTime() + ",data" + JSON.stringify(data1));let num = 0;while (true) {num++;if (num > 100000000) {console.log("任务二结束" + new Date().getTime());break;}}
}, data);

输出日志

任务一开始1706802924114
任务二开始1706802924114,data={"name":"你好"}
任务二结束1706802924196
任务一结束1706802924197
任务二开始1706802924197,data{"name":"你好"}
任务二结束1706802924271
任务一开始1706802924197,data{"name":"你好"}
任务一结束1706802924272
空闲次数: 1,如果超过2次,线程池将关闭,后续提交任务将自动开启
空闲次数: 2,如果超过2次,线程池将关闭,后续提交任务将自动开启
空闲次数: 3,如果超过2次,线程池将关闭,后续提交任务将自动开启

如果是简单的setTimeout,输出日志就是顺序执行的,非并发。

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

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

相关文章

在Windows搭建gRPC C++开发环境

本文介绍在Windows下使用Visual Studio 2017编译gRPC 1.48.0并配置开发环境&#xff0c;以及开发、配置一个简单的c服务端以及.net客户端。 0、前置条件 1、下载gRPC源码 使用git命令行在预备存放grpc源码的目录下执行, 此处我们下载的是 grpc 1.48.0 git clone -b v1.48.0 …

Pycharm python用matplotlib 3D绘图显示空白解决办法

问题原因&#xff1a; matplotlib版本升级之后显示代码变了&#xff0c;修改为新的 # ax Axes3D(fig) # 原代码 ax fig.add_axes(Axes3D(fig)) # 新代码import numpy as np import matplotlib.pyplot as plt from matplotlib import cm from mpl_toolkits.mplot3d import Ax…

测试环境搭建整套大数据系统(一:基础配置,修改hostname,hosts,免密,时间同步)

一&#xff1a;使用服务器配置。 二&#xff1a;修改服务器名称hostname&#xff0c;hosts。 在 Linux 系统中&#xff0c;hostname 和 /etc/hosts 文件分别用于管理主机名和主机名解析。 在三台服务器上&#xff0c;分别执行以下命令。 vim /etc/hostnamexdso-hadoop-test-0…

android 11 自定义Android device owner 接口

在设置里面自定义广播 去处理下面的事情 ComponentName mComponentnew ComponentName(packageName,receiverName); DevicePolicyManager mDPM.setDeviceOwner(mComponent,"d_owner_"mUserId); int mUserId android.os.Process.myPid(); int uid android.os…

༺༽༾ཊ—Unity之-04-原型模式—ཏ༿༼༻

首先创建一个项目&#xff0c; 在这个初始界面我们需要做一些准备工作&#xff0c; 建基础通用文件夹&#xff0c; 创建一个Plane 重置后 缩放100倍 加一个颜色&#xff0c; 任务1&#xff1a;使用 建造者模式 创建三种 金刚猿猴 零部件 拼接组合 首先资源商店下载 金刚猿猴 模…

常见的词法分析和语法分析的开源库收集

文章目录 一、词法及语法分析器汇总1.Flex2.Bison3.ANTLR3.Ply4.JFlex 一、词法及语法分析器汇总 1.Flex Flex是一个用于生成词法分析器的工具。它可以根据用户定义的正则表达式规则&#xff0c;将输入的字符流分割成一个个的词法单元。Flex是GNU项目的一部分&#xff0c;可以…

Redis数据淘汰策略

Redis作为一种高性能的键值存储数据库&#xff0c;通常用于缓存和提高数据检索速度。然而&#xff0c;由于内存资源有限&#xff0c;当内存不足以容纳所有数据时&#xff0c;Redis就需要采取一些策略来删除部分数据&#xff0c;以确保新的数据能够被写入。这就引入了数据淘汰策…

刨析数据结构(二)

&#x1f308;个人主页&#xff1a;小田爱学编程 &#x1f525; 系列专栏&#xff1a;数据结构————"带你无脑刨析" &#x1f3c6;&#x1f3c6;关注博主&#xff0c;随时获取更多关于数据结构的优质内容&#xff01;&#x1f3c6;&#x1f3c6; &#x1f600;欢迎…

strlen函数详解

&#x1f388;个人主页&#xff1a;甜美的江 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;c语言 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步&a…

猜凶手

日本某地发生了一件谋杀案&#xff0c;警察通过排查确定杀人凶手必为4个嫌疑犯的一个。 以下为4个嫌疑犯的供词: A说&#xff1a;不是我。 B说&#xff1a;是C。 C说&#xff1a;是D。 D说&#xff1a;C在胡说 已知3个人说了真话&#xff0c;1个人说的是假话。 现在请根据这…

动态微信小程序码和开发者工具解析小程序码

一、动态生成微信小程序码 1、方式一 微信官方网站&#xff0c;对已发布的小程序&#xff0c;提供了一个快捷的入口&#xff0c;输入微信小程序的page页面即可。 page页面可以通过右侧开启入口获取 也可以通过开发者工具左下角的页面地址和参数地址那里获取到 二、生成的小…

【软件设计师笔记】计算机系统基础知识考点

【考证须知】IT行业高含金量的证书(传送门) &#x1f496; 【软件设计师笔记】程序语言设计考点(传送门) &#x1f496; 【软件设计师笔记】操作系统考点(传送门) &#x1f496; &#x1f413; 计算机系统组成 计算机系统是由硬件和软件组成的&#xff0c;它们协同工作来运…

(Arcgis)Python编程批量将HDF5文件转换为TIFF格式并应用地理转换和投影信息

国家青藏高原科学数据中心下载中国1千米分辨率逐日全天候地表土壤水分数据集&#xff08;2003-2022&#xff09; 问题&#xff1a;数据在arcgis打开特别大&#xff0c;无法和矢量数据重合&#xff0c;没有设置地理坐标系 数据在网站上提供了投影信息&#xff0c;提示可以进行py…

WAF 无法防护的八种风险

一、目录遍历漏洞 测试用例&#xff1a;Apache 目录遍历漏洞 测试环境搭建&#xff1a; apt intsall apache2 && cd /var/www/html/ && rm index.html无法拦截原因&#xff1a; 请求中无明显恶意特征&#xff0c;无法判断为攻击行为 实战数据&#xff1a; 截…

MongoDB聚合操作

文章目录 聚合操作单一作用聚合聚合管道什么是 MongoDB 聚合框架管道&#xff08;Pipeline&#xff09;和阶段&#xff08;Stage&#xff09;常用的管道聚合阶段聚合表达式数据准备$project$match$count$group accumulator操作符$unwind$limit$skip$sort$lookup案例聚合操作案例…

【机器学习】AAAI 会议论文聚类分析

实验五&#xff1a;AAAI 会议论文聚类分析 ​ 本次实验以AAAI 2014会议论文数据为基础&#xff0c;要求实现或调用无监督聚类算法&#xff0c;了解聚类方法。 1 任务介绍 ​ 每年国际上召开的大大小小学术会议不计其数&#xff0c;发表了非常多的论文。在计算机领域的一些大…

K8s 集群可观测性-数据分流最佳实践

简介 在微服务架构下&#xff0c;一个 k8s 集群中经常会部署多套业务&#xff0c;同时也意味着不同团队、不同角色、不同的业务会在同一集群中&#xff0c;需要将不同业务的数据在不同的空间进行管理和查看。 在传统的主机环境下&#xff0c;这个是可以通过不同的主机部署 Da…

《元梦之星》赛季更新带来“新”内容,为何却被玩家集体声讨?

前段时间&#xff0c;《元梦之星》迎来了“山海奇遇”赛季的重磅更新&#xff0c;诸多“新”内容的上线吸引了很多玩家们的关注&#xff0c;然而在新版本开启之后没有多&#xff0c;新玩法新时装甚至是游戏中的新改动都引起了不少玩家的不满。 在新赛季开启之后&#xff0c;玩家…

Python爬虫http基本原理

HTTP 基本原理 在本节中&#xff0c;我们会详细了解 HTTP 的基本原理&#xff0c;了解在浏览器中敲入 URL 到获取网页内容之间发生了什么。了解了这些内容&#xff0c;有助于我们进一步了解爬虫的基本原理。 2.1.1 URI 和 URL 这里我们先了解一下 URI 和 URL&#xff0c;URI…

抖音弹幕直播玩法汉字找不同文字找不同无人值执守自动玩游戏自带语音播报的开发日志

#找不同# 要解决如下几个问题&#xff1a; 1.声音sprite的录制和调用&#xff0c;解决方案以及解决库如下&#xff1a; howler.min.js://一款不错的音频播放js库。 2.鼠标自动飘浮,使用的库 anime.min.js 3.资源预加载 preload.min.js 4.其它使用到的库 jquery,vue