nodejs中使用worker_threads来创建新的线程的方法

yizhihongxing

下面详细讲解如何在Node.js中使用worker_threads模块来创建新线程。

简介

在Node.js中,JavaScript语言具有单线程执行的特性,这意味着如果主线程执行某些任务时,会阻塞其他任务的执行进度,导致性能瓶颈。因此,可以使用worker_threads模块创建新线程,实现多线程执行任务的目的。Worker对象执行的代码并不在主线程中运行,所以它们不会阻塞主线程。

创建Worker

使用worker_threads模块创建Worker的基本语法如下:

const { Worker } = require('worker_threads');

const worker = new Worker(workerDataFile, options);

其中,workerDataFile是一个要在工作线程中运行的JS文件,而options是Workers工作条件的配置项。这样就可以创建出一个新的Worker对象,可以在这个对象上调用一些方法控制它的行为。

Worker线程的生命周期

创建Worker后,会自动创建一个新线程来执行传入的workerDataFile代码,直到它停止或被终止。Worker线程的完整生命周期如下:

  • new Worker():创建Worker对象;
  • Worker.on('message', message => {}):监听Worker线程发送的消息;
  • Worker.on('error', error => {}):监听Worker线程的错误;
  • Worker.on('exit', code => {}):监听Worker线程的退出;
  • Worker.postMessage():向Worker线程发送消息;
  • Worker.terminate():立即关闭Worker线程。

示例1:异步计算

我们来看一个Worker的示例。在这个示例中,我们创建了一个用于计算斐波那契数列的Worker。

创建一个名为calFibonacci.js的文件,代码如下:

const { parentPort } = require('worker_threads');

function fibonacci(n) {
  if (n === 0 || n === 1) {
    return n;
  } else {
    return fibonacci(n-1) + fibonacci(n-2);
  }
}

parentPort.on('message', (num) => {
  const result = fibonacci(num);
  parentPort.postMessage(result);
});

上述代码中,我们从worker_threads模块中引入parentPort对象,在这个对象上监听由主线程发来的消息。当我们收到一条消息时,就会计算斐波那契数列并将结果通过parentPort.postMessage()方法发送回主线程。

接下来,我们在主线程中创建Worker。

const { Worker } = require('worker_threads');
const path = require('path');

const worker = new Worker(path.join(__dirname, 'calFibonacci.js'));

worker.on('message', (result) => {
  console.log('计算结果:', result);
});

const num = 40;
worker.postMessage(num);
console.log('主线程计算中...');

上述代码中,我们使用path.join()方法创建Worker的workerDataFile参数,将斐波那契数列计算的工作交给Worker线程。当Worker线程完成计算后,会将结果通过worker.postMessage()方法发送回来。在主线程中,我们通过监听Worker的message事件来获取计算结果。执行这段代码后,可以看到如下输出:

主线程计算中...
计算结果: 102334155

可见,Worker线程成功地完成了斐波那契数列的计算并返回了结果。

示例2:文件读写

我们可以在Worker线程中完成磁盘IO等阻塞式操作,并让主线程继续执行不相关的工作。例如,一个计算密集型的应用程序可在一个Worker中运行而在主线程中处理IO。

在这个示例中,我们将创建一个文件读写工具,用于读取文件并将其内容写入新文件。我们将创建一个名为fileIO.js的文件用于处理此任务。

const fs = require('fs');
const { parentPort } = require('worker_threads');

const fileIO = (inputFilePath, outputFilePath) => {

  const readStream = fs.createReadStream(inputFilePath, { encoding: 'utf-8' });
  const writeStream = fs.createWriteStream(outputFilePath, { encoding: 'utf-8' });

  readStream.on('error', error => {
    console.error(`读取文件 '${inputFilePath}' 失败`, error);
    parentPort.postMessage({
      status: 'failed',
      msg: `读取文件 '${inputFilePath}' 失败`
    });
  });

  writeStream.on('error', error => {
    console.error(`写入文件 '${outputFilePath}' 失败`, error);
    parentPort.postMessage({
      status: 'failed',
      msg: `写入文件 '${outputFilePath}' 失败`
    });
  });

  writeStream.on('close', () => {
    parentPort.postMessage({
      status: 'success',
      inputFilePath,
      outputFilePath
    });
  });

  readStream.pipe(writeStream);
};

parentPort.on('message', (data) => {
  const { inputFilePath, outputFilePath } = data;
  fileIO(inputFilePath, outputFilePath);
});

上述代码中,我们从worker_threads模块中引入parentPort对象,接收由主线程发来的消息。当我们收到一条消息时,会将读取的文件结果写入新文件。如果其中任何一步操作出错,就向主线程发送一个消息。

接下来,我们在主线程中创建Worker。

const { Worker } = require('worker_threads');
const path = require('path');

const worker = new Worker(path.join(__dirname, 'fileIO.js'));

worker.on('message', (result) => {
  console.log(result);
});

const inputFilePath = path.join(__dirname, 'input.txt');
const outputFilePath = path.join(__dirname, 'output.txt');

worker.postMessage({
  inputFilePath,
  outputFilePath
});
console.log(`开始读写文件, input文件路径: ${inputFilePath}, output文件路径: ${outputFilePath}`);

上述代码中,我们使用path.join()方法创建Worker的workerDataFile参数,将文件读写的操作交给Worker线程。当Worker线程完成任务后,会将结果通过worker.postMessage()方法发送回来。在主线程中,我们通过监听Worker的message事件来获取计算结果。执行这段代码后,可以看到如下输出:

开始读写文件, input文件路径: /usr/local/nodeproject/input.txt, output文件路径: /usr/local/nodeproject/output.txt
{ status: 'success',
  inputFilePath: '/usr/local/nodeproject/input.txt',
  outputFilePath: '/usr/local/nodeproject/output.txt' }

可见,Worker线程成功地完成了文件读写任务,并成功的写入了新文件,同时向主线程发送了成功的消息。

以上就是关于如何在Node.js中使用worker_threads模块来创建新线程的详细攻略,希望可以对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:nodejs中使用worker_threads来创建新的线程的方法 - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • JS前后端实现身份证号验证代码解析

    下面是“JS前后端实现身份证号验证代码解析”的完整攻略。 前言 身份证号是人们最常用的个人身份证明,因此在各个业务场景中,我们经常需要对输入的身份证号进行格式验证。本文将介绍如何使用 JavaScript 在前后端实现身份证号验证,帮助开发者更好地应对业务需求。 方案概述 实现身份证号验证的主要过程如下: 在前端通过 JavaScript 判断用户输入的身份…

    JavaScript 2023年6月10日
    00
  • 使用JS和canvas实现gif动图的停止和播放代码

    下面是使用JS和canvas实现gif动图的停止和播放的完整攻略: 1. 了解Canvas画布和Image对象 Canvas是HTML5新增的标签,允许通过JS脚本来实现动态绘制图像。而Image对象则是JS中常见的图像对象,可以用于显示一张图片。 2. 载入GIF动图并绘制到Canvas画布上 使用Image对象来载入本地存储路径下的GIF动图文件,并将其…

    JavaScript 2023年6月10日
    00
  • 用js实现输入提示(自动完成)的实例代码

    想要实现输入提示(autocomplete)功能,我们通常需要以下几个步骤: 1. 获取用户输入 在实现自动完成功能之前,我们首先需要获取用户的输入。在网页中,我们可以通过<input>标签来实现用户输入信息的获取,例如: <label for="username">用户名:</label> <i…

    JavaScript 2023年6月10日
    00
  • JavaScript字符串对象split方法入门实例(用于把字符串分割成数组)

    当我们需要把一个字符串按照某种规则分割成一个数组时,可以使用JavaScript字符串对象的split方法。本文将详细讲解JavaScript字符串对象split方法的使用方法。 split方法基本语法 split()方法的基本语法如下: string.split(separator, limit) 其中,separator参数为分隔符,可以是字符串或正则表…

    JavaScript 2023年5月27日
    00
  • 通过js控制时间,一秒一秒自己动的实例

    下面是关于“通过JS控制时间,一秒一秒自己动”的完整攻略: 步骤一:HTML部分 首先,在HTML部分创建一个DIV元素并添加一个id,比如 #countdown。这个元素将用于显示倒计时的值。 <div id="countdown"></div> 步骤二:CSS部分 接下来,需要为倒计时的DIV元素添加样式。样式…

    JavaScript 2023年5月27日
    00
  • javascript md5加密代码

    请允许我详细讲解一下 Javascript 编程语言中如何实现 MD5 哈希加密。 什么是 MD5 哈希加密 MD5 是一种哈希算法,可以将任意长度的数据块进行不可逆转的压缩,它被广泛用于密码学的应用中,以保证密码的安全性。MD5 可以将任意长度的消息压缩为 128 bit 的摘要,并且具有不可逆性、唯一性、高效性等特点。 MD5 加密的 Javascrip…

    JavaScript 2023年5月19日
    00
  • JavaScript代码生成PDF文件的方法

    生成PDF文件是Web应用程序开发中的一个常见需求,它可以用于生成形式化文档并且作为下载文件提供给用户。虽然浏览器不具有直接生成PDF文件的功能,但是可以通过JavaScript代码调用第三方库来实现生成功能。通过以下步骤可以实现JavaScript代码生成PDF文件的方法: 步骤一:选择合适的第三方库 在实现JavaScript代码生成PDF文件的过程中,…

    JavaScript 2023年5月27日
    00
  • JavaScript 正则表达式中global模式的特性

    JavaScript 正则表达式中global模式是一种用于匹配字符串的特殊模式,具有以下特性: 全文搜索匹配:global模式可以在整个字符串中搜索,而不仅仅是搜索第一个匹配的位置。当在正则表达式中使用全局标志g时,可以进行全文搜索匹配。 下面是一个示例:假设我们有以下HTML代码: <div class="item">It…

    JavaScript 2023年6月10日
    00
合作推广
合作推广
分享本页
返回顶部